1%%-------------------------------------------------------------------- 2%% 3%% %CopyrightBegin% 4%% 5%% Copyright Ericsson AB 1999-2015. All Rights Reserved. 6%% 7%% Licensed under the Apache License, Version 2.0 (the "License"); 8%% you may not use this file except in compliance with the License. 9%% You may obtain a copy of the License at 10%% 11%% http://www.apache.org/licenses/LICENSE-2.0 12%% 13%% Unless required by applicable law or agreed to in writing, software 14%% distributed under the License is distributed on an "AS IS" BASIS, 15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16%% See the License for the specific language governing permissions and 17%% limitations under the License. 18%% 19%% %CopyrightEnd% 20%% 21%% 22%%-------------------------------------------------------------------- 23%% File : CosNotification_Common.erl 24%% Purpose : 25%%-------------------------------------------------------------------- 26 27-module('CosNotification_Common'). 28 29 30%%--------------- INCLUDES ----------------------------------- 31-include_lib("orber/include/corba.hrl"). 32%% Application files 33-include("CosNotification.hrl"). 34-include("CosNotifyChannelAdmin.hrl"). 35-include("CosNotifyComm.hrl"). 36-include("CosNotifyFilter.hrl"). 37 38-include("CosNotification_Definitions.hrl"). 39 40%%--------------- EXPORTS ------------------------------------ 41%% External MISC 42-export([get_option/3, 43 create_name/0, 44 create_name/1, 45 create_name/2, 46 create_id/0, 47 create_id/1, 48 is_debug_compiled/0, 49 type_check/2, 50 send_stubborn/5, 51 create_link/3, 52 disconnect/3, 53 do_disconnect/3, 54 notify/1]). 55 56%% Internal AdminProperties 57-export([init_adm/1, 58 set_adm/2, 59 'MaxQueueLength'/6, 60 'MaxConsumers'/6, 61 'MaxSuppliers'/6]). 62%% Internal QoS 63-export([init_qos/1, 64 set_qos/5, 65 validate_qos/5, 66 validate_event_qos/2, 67 'EventReliability'/6, 68 'ConnectionReliability'/6, 69 'Priority'/6, 70 'StartTimeSupported'/6, 71 'StopTimeSupported'/6, 72 'Timeout'/6, 73 'OrderPolicy'/6, 74 'DiscardPolicy'/6, 75 'MaximumBatchSize'/6, 76 'PacingInterval'/6, 77 'MaxEventsPerConsumer'/6]). 78 79%%--------------- DEFINITIONS OF CONSTANTS ------------------- 80%%--------------- EXTERNAL MISC FUNCTIONS -------------------- 81%%------------------------------------------------------------ 82%% function : create_link 83%% Arguments: Module - which Module to call 84%% Env/ArgList - ordinary oe_create arguments. 85%% Returns : 86%% Exception: 87%% Effect : Necessary since we want the supervisor to be a 88%% 'simple_one_for_one'. Otherwise, using for example, 89%% 'one_for_one', we have to call supervisor:delete_child 90%% to remove the childs startspecification from the 91%% supervisors internal state. 92%%------------------------------------------------------------ 93create_link(Module, Env, ArgList) -> 94 Module:oe_create_link(Env, ArgList). 95 96%%-----------------------------------------------------------% 97%% function : get_option 98%% Arguments: 99%% Returns : 100%% Exception: 101%% Effect : 102%%------------------------------------------------------------ 103get_option(Key, OptionList, DefaultList) -> 104 case lists:keysearch(Key, 1, OptionList) of 105 {value,{Key,Value}} -> 106 Value; 107 _ -> 108 case lists:keysearch(Key, 1, DefaultList) of 109 {value,{Key,Value}} -> 110 Value; 111 _-> 112 {error, "Invalid option"} 113 end 114 end. 115 116%%------------------------------------------------------------ 117%% function : create_name 118%% Arguments: 119%% Returns : 120%% Effect : Create a unique name to use when, for eaxmple, starting 121%% a new server. 122%%------------------------------------------------------------ 123create_name() -> 124 Time = erlang:system_time(), 125 Unique = erlang:unique_integer([positive]), 126 lists:concat(['oe_',node(),'_',Time,'_',Unique]). 127 128 129%%-----------------------------------------------------------% 130%% function : create_name/1 131%% Arguments: 132%% Returns : 133%% Exception: 134%% Effect : 135%%------------------------------------------------------------ 136create_name(Type) -> 137 Time = erlang:system_time(), 138 Unique = erlang:unique_integer([positive]), 139 lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]). 140 141%%-----------------------------------------------------------% 142%% function : create_name/2 143%% Arguments: 144%% Returns : 145%% Exception: 146%% Effect : 147%%------------------------------------------------------------ 148create_name(Name,Type) -> 149 Time = erlang:system_time(), 150 Unique = erlang:unique_integer([positive]), 151 lists:concat(['oe_',node(),'_',Type,'_',Name,'_',Time,'_',Unique]). 152 153%%------------------------------------------------------------ 154%% function : create_id/0 155%% Arguments: - 156%% Returns : id (long) =/= 0 157%% Both default Admin:s have the unique id 0 (OMG spec, 98-11-01, 158%% Notification p 148), hence, we may not return 0. 159%% Exception: 160%% Purpose : Throughout the CosNotification service we use, 161%% according to the OMG specification, id:s (long), 162%% which must be "unique", to retrieve object references. 163%% For example: CosNotifyChannelAdmin::ChannelId/AdminID. 164%%------------------------------------------------------------ 165create_id(-1) -> 166 1; 167create_id(2147483647) -> 168 -2147483648; 169create_id(OldID) -> 170 OldID+1. 171 172create_id() -> 173 {_A,_B,C}=erlang:timestamp(), 174 C. 175 176%%------------------------------------------------------------ 177%% function : type_check 178%% Arguments: Obj - objectrefernce to test. 179%% Mod - Module which contains typeID/0. 180%% Returns : 'ok' or raises exception. 181%% Effect : 182%%------------------------------------------------------------ 183type_check(Obj, Mod) -> 184 case cosNotificationApp:type_check() of 185 false -> 186 ok; 187 _ -> 188 case catch corba_object:is_a(Obj,Mod:typeID()) of 189 true -> 190 ok; 191 false -> 192 orber:dbg("[~p] CosNotification_Common:type_check(~p);~n" 193 "The supplied Object is not or does not inherrit from: ~p", 194 [?LINE, Obj, Mod], ?DEBUG_LEVEL), 195 corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}); 196 {'EXCEPTION', E} -> 197 orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n" 198 "Failed due to: ~p", 199 [?LINE, Obj, Mod, E], ?DEBUG_LEVEL), 200 corba:raise(E); 201 What -> 202 orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n" 203 "Failed due to: ~p", 204 [?LINE, Obj, Mod, What], ?DEBUG_LEVEL), 205 corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) 206 end 207 end. 208 209 210%%-----------------------------------------------------------% 211%% function : notify 212%% Arguments: Items - [Item] 213%% Item - {proxy, IOR} | {client, IOR} | {reason, term()} 214%% Returns : 'ok' or raises exception. 215%% Effect : 216%%------------------------------------------------------------ 217notify(Items) -> 218 case cosNotificationApp:notify() of 219 false -> 220 ok; 221 Module -> 222 catch Module:terminated(Items), 223 ok 224 end. 225 226 227%%------------------------------------------------------------ 228%% function : send_stubborn 229%% Arguments: M - module 230%% F - function 231%% A - arguments 232%% MaxR - Maximum no retries 233%% Wait - sleep Wait seconds before next try. 234%% Returns : see effect 235%% Exception: 236%% Effect : Retries repeatidly untill anything else besides 237%% 'EXIT', 'COMM_FAILURE' or 'OBJECT_NOT_EXIST' 238%%------------------------------------------------------------ 239 240send_stubborn(M, F, A, MaxR, Wait) when is_list(A) -> 241 send_stubborn(M, F, A, MaxR, Wait, 0); 242send_stubborn(M, F, A, MaxR, Wait) -> 243 send_stubborn(M, F, [A], MaxR, Wait, 0). 244send_stubborn(M, F, A, MaxR, _Wait, MaxR) -> 245 orber:dbg("[~p] CosNotification_Common:send_stubborn( ~p ~p ~p ~p).~n" 246 "Failed to deliver the event.~n", [?LINE, M,F,A,MaxR], ?DEBUG_LEVEL), 247 corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}); 248send_stubborn(M, F, A, MaxR, Wait, Times) -> 249 ?debug_print("~p:~p(~p) # of retries: ~p~n", [M,F,A, Times]), 250 case catch apply(M,F,A) of 251 {'EXCEPTION', E} when is_record(E, 'COMM_FAILURE')-> 252 NewTimes = Times +1, 253 timer:sleep(Wait), 254 send_stubborn(M, F, A, MaxR, Wait, NewTimes); 255 {'EXIT', _} -> 256 NewTimes = Times +1, 257 timer:sleep(Wait), 258 send_stubborn(M, F, A, MaxR, Wait, NewTimes); 259 Other -> 260 Other 261 end. 262 263 264%%-----------------------------------------------------------% 265%% function : disconnect 266%% Arguments: Module - one of the interfaces defined in CosEventComm. 267%% Function - the appropriate disconnect function. 268%% Object - the client object reference. 269%% Returns : ok 270%% Exception: 271%% Effect : If the process would try to diconnect itself it could 272%% result in a deadlock. Hence, we spawn a new process to do it. 273%%------------------------------------------------------------ 274disconnect(Module, Function, Object) -> 275 spawn(?MODULE, do_disconnect, [Module, Function, Object]), 276 ok. 277 278do_disconnect(Module, Function, Object) -> 279 catch Module:Function(Object), 280 ?DBG("Disconnect ~p:~p(..).~n", [Module, Function]), 281 ok. 282 283 284 285%%------------------------------------------------------------ 286%% function : is_debug_compiled 287%% Arguments: 288%% Returns : 289%% Exception: 290%% Effect : 291%%------------------------------------------------------------ 292 293-ifdef(debug). 294 is_debug_compiled() -> true. 295-else. 296 is_debug_compiled() -> false. 297-endif. 298 299 300%%------------------------------------------------------------ 301%%--------------- AdminPropertiesAdmin ----------------------- 302%%------------------------------------------------------------ 303%%------------------------------------------------------------ 304%% function : init_adm 305%% Arguments: Wanted - requested Admins to be set. 306%% Returns : #'CosNotification_UnsupportedAdmin'{} | 307%% {NewAdmProperties, [MaxQ, MaxC, MaxS]} 308%% Effect : may only be used when creating a channel!!!!!!!! 309%%------------------------------------------------------------ 310init_adm(Wanted) -> 311 {NewA,_} = set_properties(Wanted, ?not_DEFAULT_ADMINPROPERTIES, channelAdm, 312 ?not_SUPPORTED_ADMINPROPERTIES, [], [], 313 false, false, false), 314 {NewA, [extract_value(NewA, ?not_MaxQueueLength), 315 extract_value(NewA, ?not_MaxConsumers), 316 extract_value(NewA, ?not_MaxSuppliers)]}. 317 318set_adm(Wanted, Current) -> 319 {NewA,_} = set_properties(Wanted, Current, channelAdm, 320 ?not_SUPPORTED_ADMINPROPERTIES, 321 [], [], false, false, false), 322 {NewA, [extract_value(NewA, ?not_MaxQueueLength), 323 extract_value(NewA, ?not_MaxConsumers), 324 extract_value(NewA, ?not_MaxSuppliers)]}. 325 326'MaxQueueLength'(Req,channelAdm,_, _, _, _) -> admin_ok(Req). 327'MaxConsumers'(Req,channelAdm,_, _, _, _)-> admin_ok(Req). 328'MaxSuppliers'(Req,channelAdm,_, _, _, _)-> admin_ok(Req). 329 330admin_ok(Req) -> 331 case any:get_value(Req#'CosNotification_Property'.value) of 332 Val when is_integer(Val) andalso Val >= 0 -> 333 {ok, Req}; 334 _ -> 335 {unsupported, 336 #'CosNotification_PropertyError'{ 337 code = 'BAD_TYPE', 338 name = Req#'CosNotification_Property'.name, 339 available_range = #'CosNotification_PropertyRange'{ 340 low_val=any:create(orber_tc:null(), null), 341 high_val=any:create(orber_tc:null(), null) 342 } 343 } 344 } 345 end. 346 347 348%%------------------------------------------------------------ 349%%--------------- QOS FUNCTIONS ------------------------------ 350%%------------------------------------------------------------ 351%%------------------------------------------------------------ 352%% function : init_qos 353%% Arguments: Wanted - requested QoS to be set. 354%% Returns : see set_properties/9 355%% Effect : may only be used when creating a channel!!!!!!!! 356%%------------------------------------------------------------ 357init_qos(Wanted) -> 358 LQS = set_local_qos(?not_DEFAULT_QOS, ?not_CreateInitQoS()), 359 set_properties(Wanted, ?not_DEFAULT_QOS, channel, ?not_SUPPORTED_QOS, 360 [], [], false, [], LQS). 361 362%%------------------------------------------------------------ 363%% function : set_qos/5 364%% Arguments: Wanted - requested QoS to be set. 365%% Current - current QoS OMG style 366%% LQS - local representation of QoS. 367%% Type - channel | admin | proxy 368%% Parent - Factory if Channel, Channel if Admin etc 369%% Childs - Admins if Channel etc 370%% Returns : see set_properties/9 371%%------------------------------------------------------------ 372set_qos(Wanted, {Current, LQS}, proxy, Parent, _) -> 373 set_properties(Wanted, Current, proxy, ?not_SUPPORTED_QOS, [], [], Parent, false,LQS); 374set_qos(Wanted, {Current, LQS}, admin, Parent, Childs) -> 375 set_properties(Wanted, Current, admin, ?not_SUPPORTED_QOS, [], [], Parent, Childs,LQS); 376set_qos(Wanted, {Current, LQS}, channel, _, Childs) -> 377 set_properties(Wanted, Current, channel, ?not_SUPPORTED_QOS, [], [], false, Childs,LQS). 378 379%%------------------------------------------------------------ 380%% function : 381%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 382%% Type - Requestee, channel | admin | proxy 383%% Curr - Current QoS, #'CosNotification_Property'{} 384%% Parent - false | ObjRef 385%% Childs - false | [ObjRef1, .., ObjRefN] 386%% LQS - #qos{} defined in CosNotification_Definitions.hrl 387%% Returns : ok - if requested equal to current value. 388%% {ok, Req, LQS} - if new and allowed QoS 389%% {unsupported,#'CosNotification_PropertyError'{}} otherwise. 390%% Effect : 391%%------------------------------------------------------------ 392'EventReliability'(Req,channel, _Curr, _Parent, _Childs, LQS) -> 393 case {any:get_value(Req#'CosNotification_Property'.value), 394 ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of 395 {Val, Val, _, _} -> 396 %% Is the value requested. 397 ok; 398 {Val, _, Val, _} -> 399 {ok, Req, LQS}; 400 {Val, _, _, Val} -> 401 {ok, Req, LQS}; 402 _-> 403 {unsupported, 404 #'CosNotification_PropertyError'{ 405 code = 'BAD_TYPE', 406 name = Req#'CosNotification_Property'.name, 407 available_range = #'CosNotification_PropertyRange'{ 408 low_val=any:create(orber_tc:null(), null), 409 high_val=any:create(orber_tc:null(), null) 410 } 411 } 412 } 413 end; 414'EventReliability'(Req,_,_,_,_,_) -> 415 %% only valid to set this QoS for channels (or per-event). 416 {unsupported, 417 #'CosNotification_PropertyError'{ 418 code = 'UNAVAILABLE_PROPERTY', 419 name = Req#'CosNotification_Property'.name, 420 available_range = #'CosNotification_PropertyRange'{ 421 low_val=any:create(orber_tc:null(), null), 422 high_val=any:create(orber_tc:null(), null) 423 } 424 } 425 }. 426 427%%------------------------------------------------------------ 428%% function : 'ConnectionReliability'/6 429%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 430%% Type - Requestee, channel | admin | proxy 431%% Curr - Current QoS, #'CosNotification_Property'{} 432%% Parent - false | ObjRef 433%% Childs - false | [ObjRef1, .., ObjRefN] 434%% LQS - #qos{} defined in CosNotification_Definitions.hrl 435%% Returns : 436%% Exception: 437%% Effect : 438%%------------------------------------------------------------ 439%% The most complex QoS to set is ConnectionReliability, and the reason for this 440%% is that we cannot set the Channel to offer best effort while its children 441%% offer persistent. A child may only offer Persistent if its parent do, which 442%% is why we must check the following: 443%% 444%% # Persistent Change to Best Effort 445%% _____ 446%% | | (1) -> Check if children BE 447%% |Chann| (2) ok <- 448%% ----- 449%% | 450%% _____ 451%% | | (3) -> Check if children BE 452%% |Admin| (4) Check if parent Pers. <- 453%% ----- 454%% | 455%% _____ 456%% | | (5) -> ok 457%% |Proxy| (6) Check if parent Pers. <- 458%% ----- 459%% NOTE: a parent always exists but we may change the QoS before creating any 460%% childrens. The cases (2) and (5) is always ok, i.e., no need to confirm 461%% with parent or children. 462%%------------------------------------------------------------ 463'ConnectionReliability'(Req, channel, _Curr, _Parent, Childs, LQS) -> 464 case {any:get_value(Req#'CosNotification_Property'.value), 465 ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of 466 {Val, Val, _, _} -> 467 %% Is the value requested. 468 ok; 469 {Val, P, Val, P} -> 470 %% Requested is BestEffort, Current Persistent => (1) 471 check_with_relatives(Childs, Req, LQS); 472 {Val, B, B, Val} -> 473 %% Requested is Persistent, Current BestEffort => (2) 474 {ok, Req, LQS}; 475 _-> 476 {unsupported, 477 #'CosNotification_PropertyError'{ 478 code = 'BAD_TYPE', 479 name = Req#'CosNotification_Property'.name, 480 available_range = #'CosNotification_PropertyRange'{ 481 low_val=any:create(orber_tc:null(), null), 482 high_val=any:create(orber_tc:null(), null) 483 } 484 } 485 } 486 end; 487'ConnectionReliability'(Req, admin, _Curr, Parent, Childs, LQS) -> 488 case {any:get_value(Req#'CosNotification_Property'.value), 489 ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of 490 {Val, Val, _, _} -> 491 %% Is the value requested. 492 ok; 493 {Val, P, Val, P} -> 494 %% Requested is BestEffort, Current Persistent => (3) 495 check_with_relatives(Childs, Req, LQS); 496 {Val, B, B, Val} -> 497 %% Requested is Persistent, Current BestEffort => (4) 498 check_with_relatives([Parent], Req, LQS); 499 _-> 500 {unsupported, 501 #'CosNotification_PropertyError'{ 502 code = 'BAD_TYPE', 503 name = Req#'CosNotification_Property'.name, 504 available_range = #'CosNotification_PropertyRange'{ 505 low_val=any:create(orber_tc:null(), null), 506 high_val=any:create(orber_tc:null(), null) 507 } 508 } 509 } 510 end; 511'ConnectionReliability'(Req, proxy, _Curr, Parent, _Childs, LQS) -> 512 case {any:get_value(Req#'CosNotification_Property'.value), 513 ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of 514 {Val, Val, _, _} -> 515 %% Is the value requested. 516 ok; 517 {Val, P, Val, P} -> 518 %% Requested is BestEffort, Current Persistent => (5) 519 {ok, Req, LQS}; 520 {Val, B, B, Val} -> 521 %% Requested is Persistent, Current BestEffort => (6) 522 check_with_relatives([Parent], Req, LQS); 523 _-> 524 {unsupported, 525 #'CosNotification_PropertyError'{ 526 code = 'BAD_TYPE', 527 name = Req#'CosNotification_Property'.name, 528 available_range = #'CosNotification_PropertyRange'{ 529 low_val=any:create(orber_tc:null(), null), 530 high_val=any:create(orber_tc:null(), null) 531 } 532 } 533 } 534 end. 535 536%%------------------------------------------------------------ 537%% function : 'Priority'/6 538%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 539%% Type - Requestee, channel | admin | proxy 540%% Curr - Current QoS, #'CosNotification_Property'{} 541%% Parent - false | ObjRef 542%% Childs - false | [ObjRef1, .., ObjRefN] 543%% LQS - #qos{} defined in CosNotification_Definitions.hrl 544%% Returns : 545%% Effect : 546%%------------------------------------------------------------ 547'Priority'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 548 case {any:get_value(Req#'CosNotification_Property'.value), 549 ?not_GetPriority(LQS), ?not_HighestPriority, ?not_LowestPriority} of 550 {Val, Val, _, _} -> 551 ok; 552 {Val, _, H, L} when Val =< H, Val >= L -> 553 {ok, Req, LQS}; 554 {_, _, H, L} -> 555 {unsupported, 556 #'CosNotification_PropertyError'{ 557 code = 'BAD_VALUE', 558 name = Req#'CosNotification_Property'.name, 559 available_range = 560 #'CosNotification_PropertyRange'{ 561 low_val=any:create(orber_tc:short(), L), 562 high_val=any:create(orber_tc:short(), H) 563 } 564 } 565 } 566 end. 567 568%%------------------------------------------------------------ 569%% function : 'StartTimeSupported'/6 570%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 571%% Type - Requestee, channel | admin | proxy 572%% Curr - Current QoS, #'CosNotification_Property'{} 573%% Parent - false | ObjRef 574%% Childs - false | [ObjRef1, .., ObjRefN] 575%% LQS - #qos{} defined in CosNotification_Definitions.hrl 576%% Returns : 577%% Effect : 578%%------------------------------------------------------------ 579'StartTimeSupported'(Req, _Type, _Curr, _, _, LQS) -> 580 case {any:get_value(Req#'CosNotification_Property'.value), 581 ?not_GetStartTimeSupported(LQS)} of 582 {Val, Val} -> 583 ok; 584 {Val, _} when Val =/= true, Val =/= false -> 585 {unsupported, 586 #'CosNotification_PropertyError'{ 587 code = 'BAD_VALUE', 588 name = Req#'CosNotification_Property'.name, 589 available_range = 590 #'CosNotification_PropertyRange'{ 591 low_val=any:create(orber_tc:boolean(), false), 592 high_val=any:create(orber_tc:boolean(), true) 593 } 594 } 595 }; 596 _-> 597 {ok, Req, LQS} 598 end. 599 600%%------------------------------------------------------------ 601%% function : 'StopTimeSupported'/6 602%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 603%% Type - Requestee, channel | admin | proxy 604%% Curr - Current QoS, #'CosNotification_Property'{} 605%% Parent - false | ObjRef 606%% Childs - false | [ObjRef1, .., ObjRefN] 607%% LQS - #qos{} defined in CosNotification_Definitions.hrl 608%% Returns : 609%% Effect : 610%%------------------------------------------------------------ 611'StopTimeSupported'(Req, _Type, _Curr, _, _, LQS) -> 612 case {any:get_value(Req#'CosNotification_Property'.value), 613 ?not_GetStopTimeSupported(LQS)} of 614 {Val, Val} -> 615 ok; 616 {Val, _} when Val =/= true, Val =/= false -> 617 {unsupported, 618 #'CosNotification_PropertyError'{ 619 code = 'BAD_VALUE', 620 name = Req#'CosNotification_Property'.name, 621 available_range = 622 #'CosNotification_PropertyRange'{ 623 low_val=any:create(orber_tc:boolean(), false), 624 high_val=any:create(orber_tc:boolean(), true) 625 } 626 } 627 }; 628 _-> 629 {ok, Req, LQS} 630 end. 631 632%%------------------------------------------------------------ 633%% function : 'Timeout'/6 634%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 635%% Type - Requestee, channel | admin | proxy 636%% Curr - Current QoS, #'CosNotification_Property'{} 637%% Parent - false | ObjRef 638%% Childs - false | [ObjRef1, .., ObjRefN] 639%% LQS - #qos{} defined in CosNotification_Definitions.hrl 640%% Returns : 641%% Effect : 642%%------------------------------------------------------------ 643'Timeout'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 644 case {any:get_value(Req#'CosNotification_Property'.value), 645 ?not_GetTimeout(LQS)} of 646 {Val, Val} -> 647 ok; 648 {Val, _} when Val >= ?not_MinTimeout, Val =< ?not_MaxTimeout -> 649 {ok, Req, LQS}; 650 {Val, _} when is_integer(Val) -> 651 {unsupported, 652 #'CosNotification_PropertyError'{ 653 code = 'BAD_VALUE', 654 name = Req#'CosNotification_Property'.name, 655 available_range = 656 #'CosNotification_PropertyRange'{ 657 low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinTimeout), 658 high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxTimeout) 659 } 660 } 661 }; 662 _-> 663 {unsupported, 664 #'CosNotification_PropertyError'{ 665 code = 'BAD_TYPE', 666 name = Req#'CosNotification_Property'.name, 667 available_range = #'CosNotification_PropertyRange'{ 668 low_val=any:create(orber_tc:null(), null), 669 high_val=any:create(orber_tc:null(), null) 670 } 671 } 672 } 673 end. 674 675%%------------------------------------------------------------ 676%% function : 'OrderPolicy'/6 677%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 678%% Type - Requestee, channel | admin | proxy 679%% Curr - Current QoS, #'CosNotification_Property'{} 680%% Parent - false | ObjRef 681%% Childs - false | [ObjRef1, .., ObjRefN] 682%% LQS - #qos{} defined in CosNotification_Definitions.hrl 683%% Returns : 684%% Effect : 685%%------------------------------------------------------------ 686'OrderPolicy'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 687 case {any:get_value(Req#'CosNotification_Property'.value), 688 ?not_GetOrderPolicy(LQS), 'CosNotification':'AnyOrder'(), 689 'CosNotification':'PriorityOrder'()} of 690 {Val, Val,_,_} -> 691 ok; 692 {Val, _, L, H} when Val >= L, Val =< H -> 693 {ok, Req, LQS}; 694 {Val, _, L, H} when is_integer(Val) -> 695 {unsupported, 696 #'CosNotification_PropertyError'{ 697 code = 'BAD_VALUE', 698 name = Req#'CosNotification_Property'.name, 699 available_range = 700 #'CosNotification_PropertyRange'{ 701 low_val=any:create(orber_tc:short(), L), 702 high_val=any:create(orber_tc:short(), H) 703 } 704 } 705 }; 706 _-> 707 {unsupported, 708 #'CosNotification_PropertyError'{ 709 code = 'BAD_TYPE', 710 name = Req#'CosNotification_Property'.name, 711 available_range = #'CosNotification_PropertyRange'{ 712 low_val=any:create(orber_tc:null(), null), 713 high_val=any:create(orber_tc:null(), null) 714 } 715 } 716 } 717 end. 718 719 720%%------------------------------------------------------------ 721%% function : 'DiscardPolicy'/6 722%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 723%% Type - Requestee, channel | admin | proxy 724%% Curr - Current QoS, #'CosNotification_Property'{} 725%% Parent - false | ObjRef 726%% Childs - false | [ObjRef1, .., ObjRefN] 727%% LQS - #qos{} defined in CosNotification_Definitions.hrl 728%% Returns : 729%% Effect : 730%%------------------------------------------------------------ 731'DiscardPolicy'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 732 case {any:get_value(Req#'CosNotification_Property'.value), 733 ?not_GetDiscardPolicy(LQS), ?not_AnyOrder, ?not_PriorityOrder} of 734 {Val, Val,_,_} -> 735 ok; 736 {Val, _, L, H} when Val >= L, Val =< H -> 737 {ok, Req, LQS}; 738 {Val, _, L, H} when is_integer(Val) -> 739 {unsupported, 740 #'CosNotification_PropertyError'{ 741 code = 'BAD_VALUE', 742 name = Req#'CosNotification_Property'.name, 743 available_range = 744 #'CosNotification_PropertyRange'{ 745 low_val=any:create(orber_tc:short(), L), 746 high_val=any:create(orber_tc:short(), H) 747 } 748 } 749 }; 750 _-> 751 {unsupported, 752 #'CosNotification_PropertyError'{ 753 code = 'BAD_TYPE', 754 name = Req#'CosNotification_Property'.name, 755 available_range = #'CosNotification_PropertyRange'{ 756 low_val=any:create(orber_tc:null(), null), 757 high_val=any:create(orber_tc:null(), null) 758 } 759 } 760 } 761 end. 762 763%%------------------------------------------------------------ 764%% function : 'DiscardPolicy'/6 765%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 766%% Type - Requestee, channel | admin | proxy 767%% Curr - Current QoS, #'CosNotification_Property'{} 768%% Parent - false | ObjRef 769%% Childs - false | [ObjRef1, .., ObjRefN] 770%% LQS - #qos{} defined in CosNotification_Definitions.hrl 771%% Returns : 772%% Effect : 773%%------------------------------------------------------------ 774'MaximumBatchSize'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 775 case {any:get_value(Req#'CosNotification_Property'.value), 776 ?not_GetMaximumBatchSize(LQS)} of 777 {Val, Val} -> 778 ok; 779 {Val, _} when Val >= ?not_MinBatchSize, Val =< ?not_MaxBatchSize -> 780 {ok, Req, LQS}; 781 {Val, _} when is_integer(Val) -> 782 {unsupported, 783 #'CosNotification_PropertyError'{ 784 code = 'BAD_VALUE', 785 name = Req#'CosNotification_Property'.name, 786 available_range = 787 #'CosNotification_PropertyRange'{ 788 low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinBatchSize), 789 high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxBatchSize) 790 } 791 } 792 }; 793 _-> 794 {unsupported, 795 #'CosNotification_PropertyError'{ 796 code = 'UNSUPPORTED_VALUE', 797 name = Req#'CosNotification_Property'.name, 798 available_range = 799 #'CosNotification_PropertyRange'{ 800 low_val=any:create(orber_tc:long(), ?not_MinBatchSize), 801 high_val=any:create(orber_tc:long(), ?not_MaxBatchSize) 802 } 803 } 804 } 805 end. 806 807%%------------------------------------------------------------ 808%% function : 'PacingInterval'/6 809%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 810%% Type - Requestee, channel | admin | proxy 811%% Curr - Current QoS, #'CosNotification_Property'{} 812%% Parent - false | ObjRef 813%% Childs - false | [ObjRef1, .., ObjRefN] 814%% LQS - #qos{} defined in CosNotification_Definitions.hrl 815%% Returns : 816%% Comment : PacingInterval is defined to be: 817%% * TimeBase::UtcT (p 57, 2.5.5, OMG TC Document telecom/98-11-01) 818%% * TimeBase::TimeT (p 189, appendix B, OMG TC Document telecom/98-11-01) 819%% This implementation use TimeBase::TimeT, especially since 820%% TimeBase::UtcT contains information which are of no importance. 821%% When writing this, the OMG homepage contained no information 822%% regarding this. 823%%------------------------------------------------------------ 824'PacingInterval'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 825 case {any:get_value(Req#'CosNotification_Property'.value), 826 ?not_GetPacingInterval(LQS)} of 827 {Val, Val} -> 828 ok; 829 {Val, _} when Val >= ?not_MinPacing, Val =< ?not_MaxPacing -> 830 {ok, Req, LQS}; 831 {Val, _} when is_integer(Val) -> 832 {unsupported, 833 #'CosNotification_PropertyError'{ 834 code = 'BAD_VALUE', 835 name = Req#'CosNotification_Property'.name, 836 available_range = 837 #'CosNotification_PropertyRange'{ 838 low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinPacing), 839 high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxPacing) 840 } 841 } 842 }; 843 _-> 844 {unsupported, 845 #'CosNotification_PropertyError'{ 846 code = 'BAD_TYPE', 847 name = Req#'CosNotification_Property'.name, 848 available_range = #'CosNotification_PropertyRange'{ 849 low_val=any:create(orber_tc:null(), null), 850 high_val=any:create(orber_tc:null(), null) 851 } 852 } 853 } 854 end. 855 856%%------------------------------------------------------------ 857%% function : 'MaxEventsPerConsumer'/6 858%% Arguments: Req - Requested QoS, #'CosNotification_Property'{} 859%% Type - Requestee, channel | admin | proxy 860%% Curr - Current QoS, #'CosNotification_Property'{} 861%% Parent - false | ObjRef 862%% Childs - false | [ObjRef1, .., ObjRefN] 863%% LQS - #qos{} defined in CosNotification_Definitions.hrl 864%% Returns : 865%% Effect : 866%%------------------------------------------------------------ 867'MaxEventsPerConsumer'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> 868 case {any:get_value(Req#'CosNotification_Property'.value), 869 ?not_GetMaxEventsPerConsumer(LQS)} of 870 {Val, Val} -> 871 ok; 872 {Val, _} when is_integer(Val) andalso 873 Val >= ?not_MinConsumerEvents andalso 874 Val =< ?not_MaxConsumerEvents -> 875 {ok, Req, LQS}; 876 {Val, _} when is_integer(Val) -> 877 {unsupported, 878 #'CosNotification_PropertyError'{ 879 code = 'BAD_VALUE', 880 name = Req#'CosNotification_Property'.name, 881 available_range = 882 #'CosNotification_PropertyRange'{ 883 low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinConsumerEvents), 884 high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxConsumerEvents) 885 } 886 } 887 }; 888 _-> 889 {unsupported, 890 #'CosNotification_PropertyError'{ 891 code = 'UNSUPPORTED_VALUE', 892 name = Req#'CosNotification_Property'.name, 893 available_range = 894 #'CosNotification_PropertyRange'{ 895 low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents), 896 high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents) 897 } 898 } 899 } 900 end. 901 902%%------------------------------------------------------------ 903%% function : validate_qos/5 904%% Arguments: Wanted - requested QoS to be set. 905%% Curr - current QoS OMG style and LQS, local 906%% representation of QoS, grouped as {OMGQ, LQS} 907%% Type - channel | admin | proxy 908%% Parent - Factory if Channel, Channel if Admin etc 909%% Childs - Admins if Channel etc 910%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{} 911%% case 1 if all supported, case 2 if at least 1 QoS not 912%% supported. 913%% See also p59, 2.5.6.4, OMG TC Document telecom/98-11-01. Quote: 914%% "If the supplied QoS is supported, it returns additional QoS 915%% properties which could be optionally added as well." 916%%------------------------------------------------------------ 917validate_qos(Wanted, Curr, Type, Parent, Childs) -> 918 %% If not supported this function will raise an exception, which we should 919 %% not catch, but all we need to is to raise the exception as it is. 920 {_, LQS}=set_qos(Wanted, Curr, Type, Parent, Childs), 921 NewNPR = check_limits(LQS, ?not_QOS_LIMITS), 922 remove_qos(Wanted, LQS, NewNPR). 923 924remove_qos([], _, NPR) -> 925 NPR; 926remove_qos([H|T], LQS, NPR) -> 927 NewNPR=remove(NPR, H#'CosNotification_Property'.name), 928 remove_qos(T, LQS, NewNPR). 929 930check_limits(LQS, NPR) -> 931 case {?not_GetEventReliability(LQS), ?not_GetConnectionReliability(LQS), 932 ?not_Persistent, ?not_BestEffort} of 933 {P,P,P,_B} -> 934 New = #'CosNotification_NamedPropertyRange' 935 {name=?not_EventReliability, 936 range= 937 #'CosNotification_PropertyRange'{ 938 low_val=any:create(orber_tc:short(), ?not_BestEffort), 939 high_val=any:create(orber_tc:short(), ?not_BestEffort) 940 }}, 941 NewNPR=change(NPR, ?not_EventReliability, New), 942 remove(NewNPR, ?not_ConnectionReliability); 943 {_,B,_P,B} -> 944 remove(NPR, ?not_EventReliability); 945 {B,P,P,B} -> 946 New = #'CosNotification_NamedPropertyRange' 947 {name=?not_ConnectionReliability, 948 range= 949 #'CosNotification_PropertyRange'{ 950 low_val=any:create(orber_tc:short(), ?not_BestEffort), 951 high_val=any:create(orber_tc:short(), ?not_BestEffort) 952 }}, 953 change(NPR, ?not_ConnectionReliability, New) 954 end. 955 956%%------------------------------------------------------------ 957%% function : validate_event_qos/2 958%% Arguments: Wanted - requested QoS to be set. 959%% Curr - LQS, local representation of QoS 960%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{} 961%% case 1 if all supported, case 2 if at least 1 QoS not 962%% supported. 963%%------------------------------------------------------------ 964validate_event_qos(Wanted, Curr) -> 965 case v_e_q_helper(Wanted, Curr, []) of 966 ok -> 967 []; 968 {error, Unsupp} -> 969 corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp}) 970 end. 971 972v_e_q_helper([], _Curr, []) -> 973 %% Parsed all and found no conflicts. 974 ok; 975v_e_q_helper([], _Curr, Unsupp) -> 976 %% Not possible to use these requested QoS. 977 {error, Unsupp}; 978 979%%--- EventReliability ---%% 980v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability, 981 value=#any{value=?not_BestEffort}}|T], Curr, Unsupp) -> 982 %% Always ok. 983 v_e_q_helper(T, Curr, Unsupp); 984v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability, 985 value=#any{value=?not_Persistent}}|T], Curr, Unsupp) 986 when ?not_GetConnectionReliability(Curr) =/= ?not_BestEffort, 987 ?not_GetEventReliability(Curr) =/= ?not_BestEffort, 988 ?not_GetStopTimeSupported(Curr) =/= true -> 989 v_e_q_helper(T, Curr, Unsupp); 990v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability}|T], 991 Curr, Unsupp) -> 992 %% Impossible to set to Persistent if the connection reliability is best effort. 993 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 994 {code = 'UNAVAILABLE_VALUE', name = ?not_EventReliability, 995 available_range = 996 #'CosNotification_PropertyRange'{ 997 low_val=any:create(orber_tc:null(), null), 998 high_val=any:create(orber_tc:null(), null)}}|Unsupp]); 999 1000%%--- Priority ---%% 1001v_e_q_helper([#'CosNotification_Property'{name=?not_Priority, value=#any{value=V}}|T], Curr, 1002 Unsupp) -> 1003 if 1004 ?not_GetOrderPolicy(Curr) =/= ?not_AnyOrder, 1005 ?not_GetOrderPolicy(Curr) =/= ?not_Priority, 1006 ?not_GetDiscardPolicy(Curr) =/= ?not_Priority -> 1007 %% No use setting Priority since it's not currently used. 1008 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 1009 {code = 'UNAVAILABLE_VALUE', name = ?not_Priority, 1010 available_range = #'CosNotification_PropertyRange'{ 1011 low_val=any:create(orber_tc:null(), null), 1012 high_val=any:create(orber_tc:null(), null) 1013 }}|Unsupp]); 1014 V =< ?not_HighestPriority, V >= ?not_LowestPriority -> 1015 v_e_q_helper(T, Curr, Unsupp); 1016 true -> 1017 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 1018 {code = 'BAD_VALUE', name = ?not_Priority, 1019 available_range = 1020 #'CosNotification_PropertyRange'{ 1021 low_val=any:create(orber_tc:short(), 1022 ?not_LowestPriority), 1023 high_val=any:create(orber_tc:short(), 1024 ?not_HighestPriority)}}|Unsupp]) 1025 end; 1026 1027%%--- StartTime ---%% 1028v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp) 1029 when ?not_GetStartTimeSupported(Curr) =/= false, 1030 ?not_GetEventReliability(Curr) =/= ?not_Persistent -> 1031 v_e_q_helper(T, Curr, Unsupp); 1032v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp) -> 1033 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 1034 {code = 'UNAVAILABLE_VALUE', name = ?not_StartTime, 1035 available_range = #'CosNotification_PropertyRange'{ 1036 low_val=any:create(orber_tc:null(), null), 1037 high_val=any:create(orber_tc:null(), null) 1038 }}|Unsupp]); 1039 1040%%--- StopTime ---%% 1041v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp) 1042 when ?not_GetStopTimeSupported(Curr) =/= false, 1043 ?not_GetEventReliability(Curr) =/= ?not_Persistent -> 1044 v_e_q_helper(T, Curr, Unsupp); 1045v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp) -> 1046 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 1047 {code = 'UNAVAILABLE_VALUE', name = ?not_StopTime, 1048 available_range = #'CosNotification_PropertyRange'{ 1049 low_val=any:create(orber_tc:null(), null), 1050 high_val=any:create(orber_tc:null(), null) 1051 }}|Unsupp]); 1052 1053%%--- Timeout ---%% 1054v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp) 1055 when ?not_GetStopTimeSupported(Curr) =/= false, 1056 ?not_GetEventReliability(Curr) =/= ?not_Persistent -> 1057 v_e_q_helper(T, Curr, Unsupp); 1058v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp) -> 1059 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 1060 {code = 'UNAVAILABLE_VALUE', name = ?not_Timeout, 1061 available_range = #'CosNotification_PropertyRange'{ 1062 low_val=any:create(orber_tc:null(), null), 1063 high_val=any:create(orber_tc:null(), null) 1064 }}|Unsupp]); 1065 1066%%--- Unknown Event QoS ---%% 1067v_e_q_helper([#'CosNotification_Property'{name=Name}|T], Curr, Unsupp) -> 1068 %% Unsupported property. 1069 v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' 1070 {code = 'BAD_PROPERTY', name = Name, 1071 available_range = #'CosNotification_PropertyRange'{ 1072 low_val=any:create(orber_tc:null(), null), 1073 high_val=any:create(orber_tc:null(), null) 1074 }}|Unsupp]); 1075v_e_q_helper(What, _, _) -> 1076 %% Not a Property struct. 1077 orber:dbg("[~p] CosNotification_Common:v_e_q_helper(~p);~n" 1078 "Not a CosNotification_Property struct.", 1079 [?LINE, What], ?DEBUG_LEVEL), 1080 corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). 1081 1082%%-------------- QOS HELP FUNCTIONS -------------------------- 1083%%------------------------------------------------------------ 1084%% function : set_properties/9 1085%% Arguments: Wanted - requested QoS to be set. 1086%% Current - current QoS OMG style 1087%% Type - channel | admin | proxy 1088%% Supported - List of supported QoS 1089%% Unsupp - acc 1090%% NewQoS - acc 1091%% Parent - Factory if Channel, Channel if Admin etc 1092%% Childs - Admins if Channel etc 1093%% LQS - local representation of QoS. 1094%% Returns : {NewOMGStyleQoS, NewLocalQoS} | #'CosNotification_UnsupportedQoS'{} 1095%%------------------------------------------------------------ 1096set_properties(Wanted, Current, Type, Supported, Unsupp, NewQoS, Parent, Childs, LQS) -> 1097 case do_set_properties(Wanted, Current, Type, Supported, Unsupp, NewQoS, Parent, Childs, LQS) of 1098 {error, Exc} -> 1099 corba:raise(Exc); 1100 Result -> 1101 Result 1102 end. 1103 1104do_set_properties([], Curr, channelAdm, _, [], NewQoS,_,_,LAS) -> 1105 merge_properties(NewQoS, Curr, LAS); 1106do_set_properties([], Curr, _, _, [], NewQoS,_,_,LQS) -> 1107 %% set_local_qos and merge_properties are help functions found at the end of QoS 1108 %% functions. 1109 NewLQS = set_local_qos(NewQoS, LQS), 1110 merge_properties(NewQoS, Curr, NewLQS); 1111do_set_properties([], _, channelAdm, _, Unsupp, _,_,_,_) -> 1112 {error, #'CosNotification_UnsupportedAdmin'{admin_err = Unsupp}}; 1113do_set_properties([], _, _, _, Unsupp, _,_,_,_) -> 1114 {error, #'CosNotification_UnsupportedQoS'{qos_err = Unsupp}}; 1115 1116do_set_properties([Req|Tail], Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) -> 1117 %% set_values and is_supported are help functions found at the end of QoS 1118 %% functions. 1119 case set_values(is_supported(Supported, Req), Req, Type, Curr, Parent, Childs,LQS) of 1120 {unsupported, U} -> 1121 do_set_properties(Tail, Curr, Type, Supported, [U|Unsupp], NewQoS, Parent, Childs,LQS); 1122 {ok, S, NewLQS} -> 1123 do_set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,NewLQS); 1124 {ok, S} -> 1125 do_set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,LQS); 1126 ok -> 1127 do_set_properties(Tail, Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) 1128 end. 1129 1130 1131set_values(unsupported,Req,_,_,_,_,_) -> 1132 {unsupported, 1133 #'CosNotification_PropertyError'{ 1134 code = 'BAD_PROPERTY', 1135 name = Req#'CosNotification_Property'.name, 1136 available_range = #'CosNotification_PropertyRange'{ 1137 low_val=any:create(orber_tc:null(), null), 1138 high_val=any:create(orber_tc:null(), null) 1139 } 1140 } 1141 }; 1142set_values({ok, Func}, Req, Type, Curr, Parent, Childs, LQS) -> 1143 ?MODULE:Func(Req, Type, Curr, Parent, Childs, LQS). 1144 1145%% Update OMG style QoS list with new values. 1146merge_properties([], NewCurrQoS, LQS) -> 1147 {NewCurrQoS, LQS}; 1148merge_properties([H|T], Curr, LQS) -> 1149 merge_properties(T, lists:keyreplace(H#'CosNotification_Property'.name, %% get key. 1150 #'CosNotification_Property'.name, %% get index. 1151 Curr, H), LQS). 1152 1153%% Is the Property S among our supported QoS? 1154is_supported([], _) -> 1155 unsupported; 1156is_supported([{Name, Func}|_], #'CosNotification_Property'{name=Name}) -> 1157 {ok, Func}; 1158is_supported([_|T], S) -> 1159 is_supported(T, S). 1160 1161%% Find matching S-Property from a list of OMG style QoS 1162extract([], _) -> unsupported; 1163extract([H|_T], S) when H#'CosNotification_Property'.name== 1164 S#'CosNotification_Property'.name -> 1165 {ok, H}; 1166extract([_|T], S) -> extract(T,S). 1167 1168%% Find matching Property name from a list of OMG style QoS 1169extract_value([], _) -> unsupported; 1170extract_value([H|_T], Key) when H#'CosNotification_Property'.name== Key -> 1171 {ok, any:get_value(H#'CosNotification_Property'.value)}; 1172extract_value([_|T], Key) -> extract(T,Key). 1173 1174%% Remove matching S-QoS from a list of OMG style QoS 1175remove(List, Key) -> 1176 lists:keydelete(Key, 1177 #'CosNotification_NamedPropertyRange'.name, %% get index. 1178 List). 1179 1180change(List, Key, New) -> 1181 lists:keyreplace(Key, 1182 #'CosNotification_NamedPropertyRange'.name, %% get index. 1183 List, New). 1184%% Get QoS from supplied objects and check if it's the same as S. 1185check_with_relatives([], S, LQS) -> 1186 {ok, S, LQS}; 1187check_with_relatives([undefined|T], S, LQS) -> 1188 check_with_relatives(T, S, LQS); 1189check_with_relatives([H|T], S, LQS) -> 1190 case catch extract('CosNotification_QoSAdmin':get_qos(H), S) of 1191 {ok, S} -> 1192 check_with_relatives(T, S, LQS); 1193 _-> 1194 %% Varioues reasons for this case (Object not responding, not supported) 1195 {unsupported, 1196 #'CosNotification_PropertyError'{ 1197 code = 'UNAVAILABLE_PROPERTY', 1198 name = S#'CosNotification_Property'.name, 1199 available_range = #'CosNotification_PropertyRange'{ 1200 low_val=any:create(orber_tc:null(), null), 1201 high_val=any:create(orber_tc:null(), null) 1202 } 1203 } 1204 } 1205 end. 1206 1207%% Set new values to locally defined representation of QoS. Using this approach is 1208%% necessary since we must state the record-field at compile-time. 1209set_local_qos([], LQS) -> LQS; 1210set_local_qos([#'CosNotification_Property'{name=N,value=V}|T], LQS) -> 1211 NewLQS = 1212 case N of 1213 "EventReliability" -> 1214 ?not_SetEventReliability(LQS, any:get_value(V)); 1215 "ConnectionReliability" -> 1216 ?not_SetConnectionReliability(LQS, any:get_value(V)); 1217 "Priority" -> 1218 ?not_SetPriority(LQS, any:get_value(V)); 1219 "Timeout" -> 1220 ?not_SetTimeout(LQS, any:get_value(V)); 1221 "OrderPolicy" -> 1222 ?not_SetOrderPolicy(LQS, any:get_value(V)); 1223 "DiscardPolicy" -> 1224 ?not_SetDiscardPolicy(LQS, any:get_value(V)); 1225 "MaximumBatchSize" -> 1226 ?not_SetMaximumBatchSize(LQS, any:get_value(V)); 1227 "PacingInterval" -> 1228 ?not_SetPacingInterval(LQS, any:get_value(V)); 1229 "StartTimeSupported" -> 1230 ?not_SetStartTimeSupported(LQS, any:get_value(V)); 1231 "StopTimeSupported" -> 1232 ?not_SetStopTimeSupported(LQS, any:get_value(V)); 1233 "MaxEventsPerConsumer" -> 1234 ?not_SetMaxEventsPerConsumer(LQS, any:get_value(V)) 1235 end, 1236 set_local_qos(T, NewLQS). 1237 1238%%%%%%%%%%%%%%%%% END QOS FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%% 1239 1240%%--------------- END OF MODULE ------------------------------ 1241