1%%-------------------------------------------------------------------- 2%% 3%% %CopyrightBegin% 4%% 5%% Copyright Ericsson AB 2000-2016. 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 : cosTime.erl 24%% Purpose : 25%%---------------------------------------------------------------------- 26 27-module(cosTime). 28 29%%--------------- INCLUDES ----------------------------------- 30-include("cosTimeApp.hrl"). 31 32%%--------------- EXPORTS------------------------------------- 33%% cosTime API external 34-export([start/0, stop/0, 35 install_time/0, uninstall_time/0, 36 install_timerevent/0, uninstall_timerevent/0, 37 start_time_service/2, start_timerevent_service/1, stop_timerevent_service/1, 38 stop_time_service/1]). 39 40%% cosTime API internal 41-export([create_link/3, get_option/3, type_check/2, start_event_handler/1]). 42 43%% Application callbacks 44-export([start/2, init/1, stop/1]). 45 46%%--------------- DEFINES ------------------------------------ 47-define(IDL_TIME_MODULES, ['oe_TimeBase', 48 'oe_CosTime']). 49-define(IDL_TIMEREVENT_MODULES, ['oe_CosTimerEvent']). 50-define(SUPERVISOR_NAME, oe_cosTimeSup). 51-define(SUP_FLAG, {simple_one_for_one,50,10}). 52-define(SUP_TIMESERVICE_SPEC(T,I), 53 ['CosTime_TimeService',[T, I], 54 [{sup_child, true}, {regname, {global, "oe_cosTimeService"}}]]). 55-define(SUP_TIMEREVENTSERVICE_SPEC(Args), 56 ['CosTimerEvent_TimerEventService', Args, 57 [{sup_child, true}, {regname, {local, 'oe_cosTimerEventService'}}]]). 58-define(SUP_TIMEREVENTHANDLER_SPEC(Name, Args), 59 ['CosTimerEvent_TimerEventHandler',Args, 60 [{sup_child, true}, {regname, {global, Name}}]]). 61-define(SUP_CHILD, 62 {"oe_TimeChild", 63 {cosTime,create_link, []}, 64 transient,100000,worker, 65 []}). 66 67%%------------------------------------------------------------ 68%% function : install_*/X 69%% Arguments: - | Time (seconds) 70%% Returns : ok | EXIT | EXCEPTION 71%% Effect : Install necessary data in the IFR DB 72%%------------------------------------------------------------ 73 74install_time() -> 75 case install_loop(?IDL_TIME_MODULES,[]) of 76 ok -> 77 ok; 78 {error, Reason} -> 79 exit(Reason) 80 end. 81 82install_timerevent() -> 83 case install_loop(?IDL_TIMEREVENT_MODULES,[]) of 84 ok -> 85 ok; 86 {error, Reason} -> 87 exit(Reason) 88 end. 89 90install_loop([], _) -> 91 ok; 92install_loop([H|T], Accum) -> 93 case catch H:'oe_register'() of 94 {'EXIT',{unregistered,App}} -> 95 ?write_ErrorMsg("Unable to register '~p'; application ~p not registered.\n" 96 "Trying to unregister ~p\n", [H,App,Accum]), 97 uninstall_loop(Accum, {exit, register}); 98 {'EXCEPTION',_} -> 99 ?write_ErrorMsg("Unable to register '~p'; propably already registered.\n" 100 "You are adviced to confirm this.\n" 101 "Trying to unregister ~p\n", [H,Accum]), 102 uninstall_loop(Accum, {exit, register}); 103 ok -> 104 install_loop(T, [H|Accum]); 105 _ -> 106 ?write_ErrorMsg("Unable to register '~p'; reason unknown.\n" 107 "Trying to unregister ~p\n", [H,Accum]), 108 uninstall_loop(Accum, {exit, register}) 109 end. 110 111%%------------------------------------------------------------ 112%% function : uninstall_*/X 113%% Arguments: - | Time (seconds) 114%% Returns : ok | EXIT | EXCEPTION 115%% Effect : Remove data related to cosTime from the IFR DB 116%%------------------------------------------------------------ 117 118uninstall_time() -> 119 case uninstall_loop(lists:reverse(?IDL_TIME_MODULES),ok) of 120 ok -> 121 ok; 122 {error, Reason} -> 123 exit(Reason) 124 end. 125 126uninstall_timerevent() -> 127 case uninstall_loop(lists:reverse(?IDL_TIMEREVENT_MODULES),ok) of 128 ok -> 129 ok; 130 {error, Reason} -> 131 exit(Reason) 132 end. 133 134uninstall_loop([],ok) -> 135 ok; 136uninstall_loop([],{exit, register}) -> 137 {error, {?MODULE, "oe_register failed"}}; 138uninstall_loop([],{exit, unregister}) -> 139 {error, {?MODULE, "oe_unregister failed"}}; 140uninstall_loop([],{exit, both}) -> 141 {error, {?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"}}; 142uninstall_loop([H|T], Status) -> 143 case catch H:'oe_unregister'() of 144 ok -> 145 uninstall_loop(T, Status); 146 _ when Status == ok -> 147 ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n" 148 "You are adviced to confirm this.~n",[H]), 149 uninstall_loop(T, {exit, unregister}); 150 _ -> 151 ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n" 152 "You are adviced to confirm this.~n",[H]), 153 uninstall_loop(T, {exit, both}) 154 end. 155 156%%------------------------------------------------------------ 157%% function : start/stop 158%% Arguments: 159%% Returns : 160%% Effect : Starts or stops the cosTime application. 161%%------------------------------------------------------------ 162 163start() -> 164 application:start(cosTime). 165stop() -> 166 application:stop(cosTime). 167 168%%------------------------------------------------------------ 169%% function : start 170%% Arguments: Type - see module application 171%% Arg - see module application 172%% Returns : 173%% Effect : Module callback for application 174%%------------------------------------------------------------ 175 176start(_, _) -> 177 supervisor:start_link({local, ?SUPERVISOR_NAME}, cosTime, app_init). 178 179 180%%------------------------------------------------------------ 181%% function : stop 182%% Arguments: Arg - see module application 183%% Returns : 184%% Effect : Module callback for application 185%%------------------------------------------------------------ 186 187stop(_) -> 188 ok. 189 190%%------------------------------------------------------------ 191%% function : start_time_service 192%% Arguments: Tdf - time difference to UTC 193%% Inaccuracy - ulonglong 194%% Upper - inaccuracy high 195%% Returns : 196%% Effect : 197%%------------------------------------------------------------ 198start_time_service(Tdf, Inaccuracy) when is_integer(Tdf) andalso is_integer(Inaccuracy) -> 199 case supervisor:start_child(?SUPERVISOR_NAME, 200 ?SUP_TIMESERVICE_SPEC(Tdf, Inaccuracy)) of 201 {ok, Pid, Obj} when is_pid(Pid) -> 202 Obj; 203 _Other-> 204 corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) 205 end; 206start_time_service(_Tdf, _Inaccuracy) -> 207 corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). 208 209 210%%------------------------------------------------------------ 211%% function : stop_time_service 212%% Arguments: Obj - TimeService objref 213%% Returns : 214%% Effect : 215%%------------------------------------------------------------ 216stop_time_service(Obj) -> 217 corba:dispose(Obj). 218 219%%------------------------------------------------------------ 220%% function : start_timerevent_service 221%% Arguments: Timer - Timer Service Reference 222%% Returns : 223%% Effect : 224%%------------------------------------------------------------ 225start_timerevent_service(Timer) -> 226 case supervisor:start_child(?SUPERVISOR_NAME, 227 ?SUP_TIMEREVENTSERVICE_SPEC([Timer])) of 228 {ok, Pid, Obj} when is_pid(Pid) -> 229 Obj; 230 _Other-> 231 corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) 232 end. 233 234%%-----------------------------------------------------------% 235%% function : stop_timerevent_service 236%% Arguments: Obj - TimerEventService objref 237%% Returns : 238%% Effect : 239%%------------------------------------------------------------ 240stop_timerevent_service(Obj) -> 241 corba:dispose(Obj). 242 243%%-----------------------------------------------------------% 244%% function : init 245%% Arguments: 246%% Returns : 247%% Effect : 248%%------------------------------------------------------------ 249 250%% Starting using create_factory/X 251init(own_init) -> 252 {ok,{?SUP_FLAG, [?SUP_CHILD]}}; 253%% When starting as an application. 254init(app_init) -> 255 {ok,{?SUP_FLAG, [?SUP_CHILD]}}. 256 257%%-----------------------------------------------------------% 258%% function : create_link 259%% Arguments: Module - which Module to call 260%% Env/ArgList - ordinary oe_create arguments. 261%% Returns : 262%% Exception: 263%% Effect : Necessary since we want the supervisor to be a 264%% 'simple_one_for_one'. Otherwise, using for example, 265%% 'one_for_one', we have to call supervisor:delete_child 266%% to remove the childs startspecification from the 267%% supervisors internal state. 268%%------------------------------------------------------------ 269create_link(Module, Env, ArgList) -> 270 Module:oe_create_link(Env, ArgList). 271 272%%-----------------------------------------------------------% 273%% function : start_event_handler 274%% Arguments: 275%% Returns : 276%% Exception: 277%% Effect : 278%%------------------------------------------------------------ 279 280start_event_handler(Args) -> 281 Name = create_name(eventhandler), 282 case supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TIMEREVENTHANDLER_SPEC(Name,Args)) of 283 {ok, Pid, Obj} when is_pid(Pid) -> 284 Obj; 285 _Other-> 286 corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) 287 end. 288 289 290%%-----------------------------------------------------------% 291%% function : get_option 292%% Arguments: 293%% Returns : 294%% Exception: 295%% Effect : 296%%------------------------------------------------------------ 297 298get_option(Key, OptionList, DefaultList) -> 299 case lists:keysearch(Key, 1, OptionList) of 300 {value,{Key,Value}} -> 301 Value; 302 _ -> 303 case lists:keysearch(Key, 1, DefaultList) of 304 {value,{Key,Value}} -> 305 Value; 306 _-> 307 {error, "Invalid option"} 308 end 309 end. 310 311%%-----------------------------------------------------------% 312%% function : type_check 313%% Arguments: Obj - objectrefernce to test. 314%% Mod - Module which contains typeID/0. 315%% Returns : 'ok' or raises exception. 316%% Effect : 317%%------------------------------------------------------------ 318 319type_check(Obj, Mod) -> 320 case catch corba_object:is_a(Obj,Mod:typeID()) of 321 true -> 322 ok; 323 _ -> 324 corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) 325 end. 326 327 328%%-----------------------------------------------------------% 329%% function : create_name/1 330%% Arguments: 331%% Returns : 332%% Exception: 333%% Effect : 334%%------------------------------------------------------------ 335 336create_name(Type) -> 337 Time = erlang:system_time(), 338 Unique = erlang:unique_integer([positive]), 339 lists:concat(['oe_',node(),'_',Type,'_',Time,'_',Unique]). 340 341%%--------------- END OF MODULE ------------------------------ 342 343 344