aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosNotification/src/CosNotification_Common.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cosNotification/src/CosNotification_Common.erl')
-rw-r--r--lib/cosNotification/src/CosNotification_Common.erl1210
1 files changed, 1210 insertions, 0 deletions
diff --git a/lib/cosNotification/src/CosNotification_Common.erl b/lib/cosNotification/src/CosNotification_Common.erl
new file mode 100644
index 0000000000..0e0f1da0d5
--- /dev/null
+++ b/lib/cosNotification/src/CosNotification_Common.erl
@@ -0,0 +1,1210 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%--------------------------------------------------------------------
+%% File : CosNotification_Common.erl
+%% Purpose :
+%%--------------------------------------------------------------------
+
+-module('CosNotification_Common').
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%% External MISC
+-export([get_option/3,
+ create_name/2,
+ create_name/1,
+ create_id/0,
+ create_id/1,
+ is_debug_compiled/0,
+ type_check/2,
+ send_stubborn/5,
+ create_link/3,
+ disconnect/3,
+ do_disconnect/3,
+ notify/1]).
+
+%% Internal AdminProperties
+-export([init_adm/1,
+ set_adm/2,
+ 'MaxQueueLength'/6,
+ 'MaxConsumers'/6,
+ 'MaxSuppliers'/6]).
+%% Internal QoS
+-export([init_qos/1,
+ set_qos/5,
+ validate_qos/5,
+ validate_event_qos/2,
+ 'EventReliability'/6,
+ 'ConnectionReliability'/6,
+ 'Priority'/6,
+ 'StartTimeSupported'/6,
+ 'StopTimeSupported'/6,
+ 'Timeout'/6,
+ 'OrderPolicy'/6,
+ 'DiscardPolicy'/6,
+ 'MaximumBatchSize'/6,
+ 'PacingInterval'/6,
+ 'MaxEventsPerConsumer'/6]).
+
+%%--------------- DEFINITIONS OF CONSTANTS -------------------
+%%--------------- EXTERNAL MISC FUNCTIONS --------------------
+%%------------------------------------------------------------
+%% function : create_link
+%% Arguments: Module - which Module to call
+%% Env/ArgList - ordinary oe_create arguments.
+%% Returns :
+%% Exception:
+%% Effect : Necessary since we want the supervisor to be a
+%% 'simple_one_for_one'. Otherwise, using for example,
+%% 'one_for_one', we have to call supervisor:delete_child
+%% to remove the childs startspecification from the
+%% supervisors internal state.
+%%------------------------------------------------------------
+create_link(Module, Env, ArgList) ->
+ Module:oe_create_link(Env, ArgList).
+
+%%-----------------------------------------------------------%
+%% function : get_option
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+get_option(Key, OptionList, DefaultList) ->
+ case lists:keysearch(Key, 1, OptionList) of
+ {value,{Key,Value}} ->
+ Value;
+ _ ->
+ case lists:keysearch(Key, 1, DefaultList) of
+ {value,{Key,Value}} ->
+ Value;
+ _->
+ {error, "Invalid option"}
+ end
+ end.
+%%-----------------------------------------------------------%
+%% function : create_name/2
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+create_name(Name,Type) ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat(['oe_',node(),'_',Type,'_',Name,'_',MSec, '_', Sec, '_', USec]).
+
+%%-----------------------------------------------------------%
+%% function : create_name/1
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+create_name(Type) ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+
+%%------------------------------------------------------------
+%% function : create_id/0
+%% Arguments: -
+%% Returns : id (long) =/= 0
+%% Both default Admin:s have the unique id 0 (OMG spec, 98-11-01,
+%% Notification p 148), hence, we may not return 0.
+%% Exception:
+%% Purpose : Throughout the CosNotification service we use,
+%% according to the OMG specification, id:s (long),
+%% which must be "unique", to retrieve object references.
+%% For example: CosNotifyChannelAdmin::ChannelId/AdminID.
+%%------------------------------------------------------------
+create_id(-1) ->
+ 1;
+create_id( 2147483647) ->
+ -2147483648;
+create_id(OldID) ->
+ OldID+1.
+
+create_id() ->
+ {_A,_B,C}=now(),
+ C.
+
+%%-----------------------------------------------------------%
+%% function : type_check
+%% Arguments: Obj - objectrefernce to test.
+%% Mod - Module which contains typeID/0.
+%% Returns : 'ok' or raises exception.
+%% Effect :
+%%------------------------------------------------------------
+type_check(Obj, Mod) ->
+ case cosNotificationApp:type_check() of
+ false ->
+ ok;
+ _ ->
+ case catch corba_object:is_a(Obj,Mod:typeID()) of
+ true ->
+ ok;
+ false ->
+ orber:dbg("[~p] CosNotification_Common:type_check(~p);~n"
+ "The supplied Object is not or does not inherrit from: ~p",
+ [?LINE, Obj, Mod], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO});
+ {'EXCEPTION', E} ->
+ orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n"
+ "Failed due to: ~p",
+ [?LINE, Obj, Mod, E], ?DEBUG_LEVEL),
+ corba:raise(E);
+ What ->
+ orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n"
+ "Failed due to: ~p",
+ [?LINE, Obj, Mod, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end
+ end.
+
+
+%%-----------------------------------------------------------%
+%% function : notify
+%% Arguments: Items - [Item]
+%% Item - {proxy, IOR} | {client, IOR} | {reason, term()}
+%% Returns : 'ok' or raises exception.
+%% Effect :
+%%------------------------------------------------------------
+notify(Items) ->
+ case cosNotificationApp:notify() of
+ false ->
+ ok;
+ Module ->
+ catch Module:terminated(Items),
+ ok
+ end.
+
+
+%%------------------------------------------------------------
+%% function : send_stubborn
+%% Arguments: M - module
+%% F - function
+%% A - arguments
+%% MaxR - Maximum no retries
+%% Wait - sleep Wait seconds before next try.
+%% Returns : see effect
+%% Exception:
+%% Effect : Retries repeatidly untill anything else besides
+%% 'EXIT', 'COMM_FAILURE' or 'OBJECT_NOT_EXIST'
+%%------------------------------------------------------------
+
+send_stubborn(M, F, A, MaxR, Wait) when is_list(A) ->
+ send_stubborn(M, F, A, MaxR, Wait, 0);
+send_stubborn(M, F, A, MaxR, Wait) ->
+ send_stubborn(M, F, [A], MaxR, Wait, 0).
+send_stubborn(M, F, A, MaxR, _Wait, MaxR) ->
+ orber:dbg("[~p] CosNotification_Common:send_stubborn( ~p ~p ~p ~p).~n"
+ "Failed to deliver the event.~n", [?LINE, M,F,A,MaxR], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO});
+send_stubborn(M, F, A, MaxR, Wait, Times) ->
+ ?debug_print("~p:~p(~p) # of retries: ~p~n", [M,F,A, Times]),
+ case catch apply(M,F,A) of
+ {'EXCEPTION', E} when is_record(E, 'COMM_FAILURE')->
+ NewTimes = Times +1,
+ timer:sleep(Wait),
+ send_stubborn(M, F, A, MaxR, Wait, NewTimes);
+ {'EXIT', _} ->
+ NewTimes = Times +1,
+ timer:sleep(Wait),
+ send_stubborn(M, F, A, MaxR, Wait, NewTimes);
+ Other ->
+ Other
+ end.
+
+
+%%-----------------------------------------------------------%
+%% function : disconnect
+%% Arguments: Module - one of the interfaces defined in CosEventComm.
+%% Function - the appropriate disconnect function.
+%% Object - the client object reference.
+%% Returns : ok
+%% Exception:
+%% Effect : If the process would try to diconnect itself it could
+%% result in a deadlock. Hence, we spawn a new process to do it.
+%%------------------------------------------------------------
+disconnect(Module, Function, Object) ->
+ spawn(?MODULE, do_disconnect, [Module, Function, Object]),
+ ok.
+
+do_disconnect(Module, Function, Object) ->
+ catch Module:Function(Object),
+ ?DBG("Disconnect ~p:~p(..).~n", [Module, Function]),
+ ok.
+
+
+
+%%------------------------------------------------------------
+%% function : is_debug_compiled
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+
+-ifdef(debug).
+ is_debug_compiled() -> true.
+-else.
+ is_debug_compiled() -> false.
+-endif.
+
+
+%%------------------------------------------------------------
+%%--------------- AdminPropertiesAdmin -----------------------
+%%------------------------------------------------------------
+%%------------------------------------------------------------
+%% function : init_adm
+%% Arguments: Wanted - requested Admins to be set.
+%% Returns : #'CosNotification_UnsupportedAdmin'{} |
+%% {NewAdmProperties, [MaxQ, MaxC, MaxS]}
+%% Effect : may only be used when creating a channel!!!!!!!!
+%%------------------------------------------------------------
+init_adm(Wanted) ->
+ {NewA,_} = set_properties(Wanted, ?not_DEFAULT_ADMINPROPERTIES, channelAdm,
+ ?not_SUPPORTED_ADMINPROPERTIES, [], [],
+ false, false, false),
+ {NewA, [extract_value(NewA, ?not_MaxQueueLength),
+ extract_value(NewA, ?not_MaxConsumers),
+ extract_value(NewA, ?not_MaxSuppliers)]}.
+
+set_adm(Wanted, Current) ->
+ {NewA,_} = set_properties(Wanted, Current, channelAdm,
+ ?not_SUPPORTED_ADMINPROPERTIES,
+ [], [], false, false, false),
+ {NewA, [extract_value(NewA, ?not_MaxQueueLength),
+ extract_value(NewA, ?not_MaxConsumers),
+ extract_value(NewA, ?not_MaxSuppliers)]}.
+
+'MaxQueueLength'(Req,channelAdm,_, _, _, _) -> admin_ok(Req).
+'MaxConsumers'(Req,channelAdm,_, _, _, _)-> admin_ok(Req).
+'MaxSuppliers'(Req,channelAdm,_, _, _, _)-> admin_ok(Req).
+
+admin_ok(Req) ->
+ case any:get_value(Req#'CosNotification_Property'.value) of
+ Val when is_integer(Val) andalso Val >= 0 ->
+ {ok, Req};
+ _ ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+
+%%------------------------------------------------------------
+%%--------------- QOS FUNCTIONS ------------------------------
+%%------------------------------------------------------------
+%%------------------------------------------------------------
+%% function : init_qos
+%% Arguments: Wanted - requested QoS to be set.
+%% Returns : see set_properties/9
+%% Effect : may only be used when creating a channel!!!!!!!!
+%%------------------------------------------------------------
+init_qos(Wanted) ->
+ LQS = set_local_qos(?not_DEFAULT_QOS, ?not_CreateInitQoS()),
+ set_properties(Wanted, ?not_DEFAULT_QOS, channel, ?not_SUPPORTED_QOS,
+ [], [], false, [], LQS).
+
+%%------------------------------------------------------------
+%% function : set_qos/5
+%% Arguments: Wanted - requested QoS to be set.
+%% Current - current QoS OMG style
+%% LQS - local representation of QoS.
+%% Type - channel | admin | proxy
+%% Parent - Factory if Channel, Channel if Admin etc
+%% Childs - Admins if Channel etc
+%% Returns : see set_properties/9
+%%------------------------------------------------------------
+set_qos(Wanted, {Current, LQS}, proxy, Parent, _) ->
+ set_properties(Wanted, Current, proxy, ?not_SUPPORTED_QOS, [], [], Parent, false,LQS);
+set_qos(Wanted, {Current, LQS}, admin, Parent, Childs) ->
+ set_properties(Wanted, Current, admin, ?not_SUPPORTED_QOS, [], [], Parent, Childs,LQS);
+set_qos(Wanted, {Current, LQS}, channel, _, Childs) ->
+ set_properties(Wanted, Current, channel, ?not_SUPPORTED_QOS, [], [], false, Childs,LQS).
+
+%%------------------------------------------------------------
+%% function :
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns : ok - if requested equal to current value.
+%% {ok, Req, LQS} - if new and allowed QoS
+%% {unsupported,#'CosNotification_PropertyError'{}} otherwise.
+%% Effect :
+%%------------------------------------------------------------
+'EventReliability'(Req,channel, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, _, Val, _} ->
+ {ok, Req, LQS};
+ {Val, _, _, Val} ->
+ {ok, Req, LQS};
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end;
+'EventReliability'(Req,_,_,_,_,_) ->
+ %% only valid to set this QoS for channels (or per-event).
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNAVAILABLE_PROPERTY',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }.
+
+%%------------------------------------------------------------
+%% function : 'ConnectionReliability'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+%% The most complex QoS to set is ConnectionReliability, and the reason for this
+%% is that we cannot set the Channel to offer best effort while its children
+%% offer persistent. A child may only offer Persistent if its parent do, which
+%% is why we must check the following:
+%%
+%% # Persistent Change to Best Effort
+%% _____
+%% | | (1) -> Check if children BE
+%% |Chann| (2) ok <-
+%% -----
+%% |
+%% _____
+%% | | (3) -> Check if children BE
+%% |Admin| (4) Check if parent Pers. <-
+%% -----
+%% |
+%% _____
+%% | | (5) -> ok
+%% |Proxy| (6) Check if parent Pers. <-
+%% -----
+%% NOTE: a parent always exists but we may change the QoS before creating any
+%% childrens. The cases (2) and (5) is always ok, i.e., no need to confirm
+%% with parent or children.
+%%------------------------------------------------------------
+'ConnectionReliability'(Req, channel, _Curr, _Parent, Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, P, Val, P} ->
+ %% Requested is BestEffort, Current Persistent => (1)
+ check_with_relatives(Childs, Req, LQS);
+ {Val, B, B, Val} ->
+ %% Requested is Persistent, Current BestEffort => (2)
+ {ok, Req, LQS};
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end;
+'ConnectionReliability'(Req, admin, _Curr, Parent, Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, P, Val, P} ->
+ %% Requested is BestEffort, Current Persistent => (3)
+ check_with_relatives(Childs, Req, LQS);
+ {Val, B, B, Val} ->
+ %% Requested is Persistent, Current BestEffort => (4)
+ check_with_relatives([Parent], Req, LQS);
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end;
+'ConnectionReliability'(Req, proxy, _Curr, Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, P, Val, P} ->
+ %% Requested is BestEffort, Current Persistent => (5)
+ {ok, Req, LQS};
+ {Val, B, B, Val} ->
+ %% Requested is Persistent, Current BestEffort => (6)
+ check_with_relatives([Parent], Req, LQS);
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'Priority'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'Priority'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetPriority(LQS), ?not_HighestPriority, ?not_LowestPriority} of
+ {Val, Val, _, _} ->
+ ok;
+ {Val, _, H, L} when Val =< H, Val >= L ->
+ {ok, Req, LQS};
+ {_, _, H, L} ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), L),
+ high_val=any:create(orber_tc:short(), H)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'StartTimeSupported'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'StartTimeSupported'(Req, _Type, _Curr, _, _, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetStartTimeSupported(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val =/= true, Val =/= false ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:boolean(), false),
+ high_val=any:create(orber_tc:boolean(), true)
+ }
+ }
+ };
+ _->
+ {ok, Req, LQS}
+ end.
+
+%%------------------------------------------------------------
+%% function : 'StopTimeSupported'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'StopTimeSupported'(Req, _Type, _Curr, _, _, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetStopTimeSupported(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val =/= true, Val =/= false ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:boolean(), false),
+ high_val=any:create(orber_tc:boolean(), true)
+ }
+ }
+ };
+ _->
+ {ok, Req, LQS}
+ end.
+
+%%------------------------------------------------------------
+%% function : 'Timeout'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'Timeout'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetTimeout(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val >= ?not_MinTimeout, Val =< ?not_MaxTimeout ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinTimeout),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxTimeout)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'OrderPolicy'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'OrderPolicy'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetOrderPolicy(LQS), 'CosNotification':'AnyOrder'(),
+ 'CosNotification':'PriorityOrder'()} of
+ {Val, Val,_,_} ->
+ ok;
+ {Val, _, L, H} when Val >= L, Val =< H ->
+ {ok, Req, LQS};
+ {Val, _, L, H} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), L),
+ high_val=any:create(orber_tc:short(), H)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+
+%%------------------------------------------------------------
+%% function : 'DiscardPolicy'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'DiscardPolicy'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetDiscardPolicy(LQS), ?not_AnyOrder, ?not_PriorityOrder} of
+ {Val, Val,_,_} ->
+ ok;
+ {Val, _, L, H} when Val >= L, Val =< H ->
+ {ok, Req, LQS};
+ {Val, _, L, H} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), L),
+ high_val=any:create(orber_tc:short(), H)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'DiscardPolicy'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'MaximumBatchSize'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetMaximumBatchSize(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val >= ?not_MinBatchSize, Val =< ?not_MaxBatchSize ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinBatchSize),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxBatchSize)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNSUPPORTED_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:long(), ?not_MinBatchSize),
+ high_val=any:create(orber_tc:long(), ?not_MaxBatchSize)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'PacingInterval'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Comment : PacingInterval is defined to be:
+%% * TimeBase::UtcT (p 57, 2.5.5, OMG TC Document telecom/98-11-01)
+%% * TimeBase::TimeT (p 189, appendix B, OMG TC Document telecom/98-11-01)
+%% This implementation use TimeBase::TimeT, especially since
+%% TimeBase::UtcT contains information which are of no importance.
+%% When writing this, the OMG homepage contained no information
+%% regarding this.
+%%------------------------------------------------------------
+'PacingInterval'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetPacingInterval(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val >= ?not_MinPacing, Val =< ?not_MaxPacing ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinPacing),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxPacing)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'MaxEventsPerConsumer'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'MaxEventsPerConsumer'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetMaxEventsPerConsumer(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when is_integer(Val) andalso
+ Val >= ?not_MinConsumerEvents andalso
+ Val =< ?not_MaxConsumerEvents ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinConsumerEvents),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxConsumerEvents)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNSUPPORTED_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents),
+ high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : validate_qos/5
+%% Arguments: Wanted - requested QoS to be set.
+%% Curr - current QoS OMG style and LQS, local
+%% representation of QoS, grouped as {OMGQ, LQS}
+%% Type - channel | admin | proxy
+%% Parent - Factory if Channel, Channel if Admin etc
+%% Childs - Admins if Channel etc
+%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{}
+%% case 1 if all supported, case 2 if at least 1 QoS not
+%% supported.
+%% See also p59, 2.5.6.4, OMG TC Document telecom/98-11-01. Quote:
+%% "If the supplied QoS is supported, it returns additional QoS
+%% properties which could be optionally added as well."
+%%------------------------------------------------------------
+validate_qos(Wanted, Curr, Type, Parent, Childs) ->
+ %% If not supported this function will raise an exception, which we should
+ %% not catch, but all we need to is to raise the exception as it is.
+ {_, LQS}=set_qos(Wanted, Curr, Type, Parent, Childs),
+ NewNPR = check_limits(LQS, ?not_QOS_LIMITS),
+ remove_qos(Wanted, LQS, NewNPR).
+
+remove_qos([], _, NPR) ->
+ NPR;
+remove_qos([H|T], LQS, NPR) ->
+ NewNPR=remove(NPR, H#'CosNotification_Property'.name),
+ remove_qos(T, LQS, NewNPR).
+
+check_limits(LQS, NPR) ->
+ case {?not_GetEventReliability(LQS), ?not_GetConnectionReliability(LQS),
+ ?not_Persistent, ?not_BestEffort} of
+ {P,P,P,_B} ->
+ New = #'CosNotification_NamedPropertyRange'
+ {name=?not_EventReliability,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_BestEffort),
+ high_val=any:create(orber_tc:short(), ?not_BestEffort)
+ }},
+ NewNPR=change(NPR, ?not_EventReliability, New),
+ remove(NewNPR, ?not_ConnectionReliability);
+ {_,B,_P,B} ->
+ remove(NPR, ?not_EventReliability);
+ {B,P,P,B} ->
+ New = #'CosNotification_NamedPropertyRange'
+ {name=?not_ConnectionReliability,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_BestEffort),
+ high_val=any:create(orber_tc:short(), ?not_BestEffort)
+ }},
+ change(NPR, ?not_ConnectionReliability, New)
+ end.
+
+%%------------------------------------------------------------
+%% function : validate_event_qos/2
+%% Arguments: Wanted - requested QoS to be set.
+%% Curr - LQS, local representation of QoS
+%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{}
+%% case 1 if all supported, case 2 if at least 1 QoS not
+%% supported.
+%%------------------------------------------------------------
+validate_event_qos(Wanted, Curr) ->
+ v_e_q_helper(Wanted, Curr, []),
+ [].
+v_e_q_helper([], _Curr, []) ->
+ %% Parsed all and foynd no conflicts.
+ ok;
+v_e_q_helper([], _Curr, Unsupp) ->
+ %% Not possible to use these requested QoS.
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});
+
+%%--- EventReliability ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability,
+ value=#any{value=?not_BestEffort}}|T], Curr, Unsupp) ->
+ %% Always ok.
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability,
+ value=#any{value=?not_Persistent}}|T], Curr, Unsupp)
+ when ?not_GetConnectionReliability(Curr) =/= ?not_BestEffort,
+ ?not_GetEventReliability(Curr) =/= ?not_BestEffort,
+ ?not_GetStopTimeSupported(Curr) =/= true ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability}|T],
+ Curr, Unsupp) ->
+ %% Impossible to set to Persistent if the connection reliability is best effort.
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_EventReliability,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)}}|Unsupp]);
+
+%%--- Priority ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_Priority, value=#any{value=V}}|T], Curr,
+ Unsupp) ->
+ if
+ ?not_GetOrderPolicy(Curr) =/= ?not_AnyOrder,
+ ?not_GetOrderPolicy(Curr) =/= ?not_Priority,
+ ?not_GetDiscardPolicy(Curr) =/= ?not_Priority ->
+ %% No use setting Priority since it's not currently used.
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_Priority,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+ V =< ?not_HighestPriority, V >= ?not_LowestPriority ->
+ v_e_q_helper(T, Curr, Unsupp);
+ true ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'BAD_VALUE', name = ?not_Priority,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(),
+ ?not_LowestPriority),
+ high_val=any:create(orber_tc:short(),
+ ?not_HighestPriority)}}|Unsupp])
+ end;
+
+%%--- StartTime ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp)
+ when ?not_GetStartTimeSupported(Curr) =/= false,
+ ?not_GetEventReliability(Curr) =/= ?not_Persistent ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp) ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_StartTime,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+
+%%--- StopTime ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp)
+ when ?not_GetStopTimeSupported(Curr) =/= false,
+ ?not_GetEventReliability(Curr) =/= ?not_Persistent ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp) ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_StopTime,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+
+%%--- Timeout ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp)
+ when ?not_GetStopTimeSupported(Curr) =/= false,
+ ?not_GetEventReliability(Curr) =/= ?not_Persistent ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp) ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_Timeout,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+
+%%--- Unknown Event QoS ---%%
+v_e_q_helper([#'CosNotification_Property'{name=Name}|T], Curr, Unsupp) ->
+ %% Unsupported property.
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'BAD_PROPERTY', name = Name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+v_e_q_helper(What, _, _) ->
+ %% Not a Property struct.
+ orber:dbg("[~p] CosNotification_Common:v_e_q_helper(~p);~n"
+ "Not a CosNotification_Property struct.",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%-------------- QOS HELP FUNCTIONS --------------------------
+%%------------------------------------------------------------
+%% function : set_properties/9
+%% Arguments: Wanted - requested QoS to be set.
+%% Current - current QoS OMG style
+%% Type - channel | admin | proxy
+%% Supported - List of supported QoS
+%% Unsupp - acc
+%% NewQoS - acc
+%% Parent - Factory if Channel, Channel if Admin etc
+%% Childs - Admins if Channel etc
+%% LQS - local representation of QoS.
+%% Returns : {NewOMGStyleQoS, NewLocalQoS} | #'CosNotification_UnsupportedQoS'{}
+%%------------------------------------------------------------
+set_properties([], Curr, channelAdm, _, [], NewQoS,_,_,LAS) ->
+ merge_properties(NewQoS, Curr, LAS);
+set_properties([], Curr, _, _, [], NewQoS,_,_,LQS) ->
+ %% set_local_qos and merge_properties are help functions found at the end of QoS
+ %% functions.
+ NewLQS = set_local_qos(NewQoS, LQS),
+ merge_properties(NewQoS, Curr, NewLQS);
+set_properties([], _, channelAdm, _, Unsupp, _,_,_,_) ->
+ corba:raise(#'CosNotification_UnsupportedAdmin'{admin_err = Unsupp});
+set_properties([], _, _, _, Unsupp, _,_,_,_) ->
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});
+
+set_properties([Req|Tail], Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) ->
+ %% set_values and is_supported are help functions found at the end of QoS
+ %% functions.
+ case set_values(is_supported(Supported, Req), Req, Type, Curr, Parent, Childs,LQS) of
+ {unsupported, U} ->
+ set_properties(Tail, Curr, Type, Supported, [U|Unsupp], NewQoS, Parent, Childs,LQS);
+ {ok, S, NewLQS} ->
+ set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,NewLQS);
+ {ok, S} ->
+ set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,LQS);
+ ok ->
+ set_properties(Tail, Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS)
+ end.
+
+
+set_values(unsupported,Req,_,_,_,_,_) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_PROPERTY',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ };
+set_values({ok, Func}, Req, Type, Curr, Parent, Childs, LQS) ->
+ ?MODULE:Func(Req, Type, Curr, Parent, Childs, LQS).
+
+%% Update OMG style QoS list with new values.
+merge_properties([], NewCurrQoS, LQS) ->
+ {NewCurrQoS, LQS};
+merge_properties([H|T], Curr, LQS) ->
+ merge_properties(T, lists:keyreplace(H#'CosNotification_Property'.name, %% get key.
+ #'CosNotification_Property'.name, %% get index.
+ Curr, H), LQS).
+
+%% Is the Property S among our supported QoS?
+is_supported([], _) ->
+ unsupported;
+is_supported([{Name, Func}|_], #'CosNotification_Property'{name=Name}) ->
+ {ok, Func};
+is_supported([_|T], S) ->
+ is_supported(T, S).
+
+%% Find matching S-Property from a list of OMG style QoS
+extract([], _) -> unsupported;
+extract([H|_T], S) when H#'CosNotification_Property'.name==
+ S#'CosNotification_Property'.name ->
+ {ok, H};
+extract([_|T], S) -> extract(T,S).
+
+%% Find matching Property name from a list of OMG style QoS
+extract_value([], _) -> unsupported;
+extract_value([H|_T], Key) when H#'CosNotification_Property'.name== Key ->
+ {ok, any:get_value(H#'CosNotification_Property'.value)};
+extract_value([_|T], Key) -> extract(T,Key).
+
+%% Remove matching S-QoS from a list of OMG style QoS
+remove(List, Key) ->
+ lists:keydelete(Key,
+ #'CosNotification_NamedPropertyRange'.name, %% get index.
+ List).
+
+change(List, Key, New) ->
+ lists:keyreplace(Key,
+ #'CosNotification_NamedPropertyRange'.name, %% get index.
+ List, New).
+%% Get QoS from supplied objects and check if it's the same as S.
+check_with_relatives([], S, LQS) ->
+ {ok, S, LQS};
+check_with_relatives([undefined|T], S, LQS) ->
+ check_with_relatives(T, S, LQS);
+check_with_relatives([H|T], S, LQS) ->
+ case catch extract('CosNotification_QoSAdmin':get_qos(H), S) of
+ {ok, S} ->
+ check_with_relatives(T, S, LQS);
+ _->
+ %% Varioues reasons for this case (Object not responding, not supported)
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNAVAILABLE_PROPERTY',
+ name = S#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%% Set new values to locally defined representation of QoS. Using this approach is
+%% necessary since we must state the record-field at compile-time.
+set_local_qos([], LQS) -> LQS;
+set_local_qos([#'CosNotification_Property'{name=N,value=V}|T], LQS) ->
+ NewLQS =
+ case N of
+ "EventReliability" ->
+ ?not_SetEventReliability(LQS, any:get_value(V));
+ "ConnectionReliability" ->
+ ?not_SetConnectionReliability(LQS, any:get_value(V));
+ "Priority" ->
+ ?not_SetPriority(LQS, any:get_value(V));
+ "Timeout" ->
+ ?not_SetTimeout(LQS, any:get_value(V));
+ "OrderPolicy" ->
+ ?not_SetOrderPolicy(LQS, any:get_value(V));
+ "DiscardPolicy" ->
+ ?not_SetDiscardPolicy(LQS, any:get_value(V));
+ "MaximumBatchSize" ->
+ ?not_SetMaximumBatchSize(LQS, any:get_value(V));
+ "PacingInterval" ->
+ ?not_SetPacingInterval(LQS, any:get_value(V));
+ "StartTimeSupported" ->
+ ?not_SetStartTimeSupported(LQS, any:get_value(V));
+ "StopTimeSupported" ->
+ ?not_SetStopTimeSupported(LQS, any:get_value(V));
+ "MaxEventsPerConsumer" ->
+ ?not_SetMaxEventsPerConsumer(LQS, any:get_value(V))
+ end,
+ set_local_qos(T, NewLQS).
+
+%%%%%%%%%%%%%%%%% END QOS FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%--------------- END OF MODULE ------------------------------