%%-------------------------------------------------------------------- %% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2000-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 : CosTime_TimeService_impl.erl %% Purpose : %%---------------------------------------------------------------------- -module('CosTime_TimeService_impl'). %%--------------- INCLUDES ----------------------------------- -include("cosTimeApp.hrl"). %%--------------- EXPORTS ------------------------------------ %%--------------- External ----------------------------------- %% Interface functions -export([universal_time/2, secure_universal_time/2, new_universal_time/5]). -export([uto_from_utc/3, new_interval/4]). %%--------------- gen_server specific exports ---------------- -export([handle_info/2, code_change/3]). -export([init/1, terminate/2]). %% Data structures -record(state, {tdf, inaccuracy}). %% Data structures constructors -define(get_InitState(T,I), #state{tdf = T, inaccuracy = I}). %% Data structures selectors -define(get_Inaccuracy(S), S#state.inaccuracy). -define(get_Tdf(S), S#state.tdf). %% Data structures modifiers %% MISC %%-----------------------------------------------------------% %% function : handle_info, code_change %% Arguments: %% Returns : %% Effect : Functions demanded by the gen_server module. %%------------------------------------------------------------ code_change(_OldVsn, State, _Extra) -> {ok, State}. handle_info(_Info, State) -> ?debug_print("INFO: ~p~n", [_Info]), {noreply, State}. %%----------------------------------------------------------% %% function : init, terminate %% Arguments: %%----------------------------------------------------------- init([Tdf, Inaccuracy]) -> process_flag(trap_exit, true), {ok, ?get_InitState(Tdf, Inaccuracy)}. terminate(_Reason, _State) -> ok. %%----------------------------------------------------------- %%------- Exported external functions ----------------------- %%----------------------------------------------------------- %%----------------------------------------------------------% %% function : universal_time %% Arguments: - %% Returns : CosTime::UTO | %% {'EXCEPTION", #'CosTime_TimeUnavailable'{}} %% NOTE : cosTime:create_universal_time will raise the correct %% exception. %%----------------------------------------------------------- universal_time(OE_THIS, State) -> {ok, Time} = create_universal_time(), Inaccuracy = ?get_Inaccuracy(State), Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy), inacchi = ?high_TimeT(Inaccuracy), tdf = ?get_Tdf(State)}, {reply, 'CosTime_UTO':oe_create([Utc, OE_THIS], [{pseudo,true}|?CREATE_OPTS]), State}. %%----------------------------------------------------------% %% function : secure_universal_time %% Arguments: %% Returns : {'EXCEPTION", #'CosTime_TimeUnavailable'{}} %%----------------------------------------------------------- secure_universal_time(_OE_THIS, _State) -> corba:raise(#'CosTime_TimeUnavailable'{}). %%----------------------------------------------------------% %% function : new_universal_time %% Arguments: Time - TimeBase::TimeT %% Inaccuracy - TimeBase::InaccuracyT inaccuracy %% Tdf - TimeBase::TdfT %% Returns : CosTime::UTO %%----------------------------------------------------------- new_universal_time(OE_THIS, State, Time, Inaccuracy, Tdf) when is_integer(Time) andalso is_integer(Inaccuracy) andalso is_integer(Tdf) andalso Tdf=<12 andalso Inaccuracy=<?max_Inaccuracy andalso Time=<?max_TimeT -> Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy), inacchi = ?high_TimeT(Inaccuracy), tdf = Tdf}, {reply, 'CosTime_UTO':oe_create([Utc, OE_THIS], [{pseudo,true}|?CREATE_OPTS]), State}; new_universal_time(_, _, _, _, _) -> corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). %%----------------------------------------------------------% %% function : uto_from_utc %% Arguments: Utc - TimeBase::UtcT %% Returns : CosTime::UTO %%----------------------------------------------------------- uto_from_utc(OE_THIS, State, Utc) when is_record(Utc, 'TimeBase_UtcT') -> {reply, 'CosTime_UTO':oe_create([Utc, OE_THIS],[{pseudo,true}|?CREATE_OPTS]),State}; uto_from_utc(_, _, _) -> corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). %%----------------------------------------------------------% %% function : new_interval %% Arguments: Lower - TimeBase::TimeT %% Upper - TimeBase::TimeT %% Returns : CosTime::TIO %%----------------------------------------------------------- new_interval(OE_THIS, State, Lower, Upper) when is_integer(Lower) andalso is_integer(Upper) andalso Lower=<Upper -> {reply, 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=Lower, upper_bound=Upper}, ?get_Tdf(State), OE_THIS], [{pseudo,true}|?CREATE_OPTS]), State}; new_interval(_, _, _, _) -> corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). %%--------------- LOCAL FUNCTIONS ---------------------------- %%-----------------------------------------------------------% %% function : create_universal_utc %% Arguments: - %% Returns : TimeT or raises exception. %% Effect : Creates a universal time; if time unavailable we %% must raise CosTime_TimeUnavailable. %% NOTE : 'datetime_to_gregorian_seconds' use year 0 as time %% base. We want to use 15 october 1582, 00:00 as base. %%------------------------------------------------------------ create_universal_time() -> %% Time is supposed to be #100 nano-secs passed. %% We add micro secs for a greater precision. {MS,S,US} = erlang:timestamp(), case catch calendar:datetime_to_gregorian_seconds( calendar:now_to_universal_time({MS,S,US})) of Secs when is_integer(Secs) -> {ok, (Secs-?ABSOLUTE_TIME_DIFF)*10000000 + US*10}; _ -> corba:raise(#'CosTime_TimeUnavailable'{}) end. %%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- %%--------------- END OF MODULE ------------------------------