1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%
22%%----------------------------------------------------------------------
23%% Purpose:
24%%----------------------------------------------------------------------
25-module(megaco_tc_controller).
26
27-export([start_link/0, stop/0,
28	 insert/2, lookup/1, delete/1]).
29-export([init/2]).
30
31-include("megaco_test_lib.hrl").
32
33-define(SERVER, ?MODULE).
34-define(TABLE,  ?MODULE).
35
36start_link() ->
37    p("start_link -> entry"),
38    Pid = spawn_link(?MODULE, init, [self(),get(dbg)]),
39    receive
40	{tc_started, Pid, Reply} ->
41	    p("start_link -> ~n   ~p", [Reply]),
42	    Reply
43    end.
44
45stop() ->
46    request(stop, undefined).
47
48insert(Key, Val) ->
49    request(insert, {Key, Val}).
50
51lookup(Key) ->
52    case request(lookup, Key) of
53	{value, _} = Value ->
54	    Value;
55	_ ->
56	    false
57    end.
58
59delete(Key) ->
60    request(delete, Key).
61
62request(Tag, Data) ->
63    p("request -> entry with"
64      "~n   Tag:  ~p"
65      "~n   Data: ~p", [Tag, Data]),
66    case global:whereis_name(?SERVER) of
67	Pid when is_pid(Pid) ->
68	    Pid ! {Tag, self(), Data},
69	    receive
70		{Tag, Pid, Reply} ->
71		    p("request -> response: "
72		      "~n   Reply: ~p", [Reply]),
73		    Reply
74	    end;
75	_ ->
76	    {error, not_started}
77    end.
78
79init(Parent, true) ->
80    put(dbg,true),
81    init(Parent);
82init(Parent, _) ->
83    init(Parent).
84
85init(Parent) ->
86    p("init -> entry with"
87      "~n   Parent: ~p", [Parent]),
88    ets:new(?TABLE, [named_table, protected, set]),
89    case global:register_name(?SERVER, self()) of
90	yes ->
91	    p("init -> registration ok"),
92	    Parent ! {tc_started, self(), ok},
93	    loop(Parent);
94	no ->
95	    p("init -> registration failed"),
96	    Parent ! {tc_started, self(), {error, already_registered}},
97	    exit(normal)
98    end.
99
100loop(Parent) ->
101    p("loop -> entry"),
102    receive
103	{insert, Parent, {Key, Val}} ->
104	    p("loop -> received insert request when"
105	      "~n   Key: ~p"
106	      "~n   Val: ~p", [Key, Val]),
107	    ets:insert(?TABLE, {Key, Val}),
108	    Parent ! {insert, self(), ok};
109	{delete, Parent, Key} ->
110	    p("loop -> received delete request when"
111	      "~n   Key: ~p", [Key]),
112	    ets:delete(?TABLE, Key),
113	    Parent ! {delete, self(), ok};
114	{lookup, From, Key} when is_pid(From) ->
115	    p("loop -> received lookup request when"
116	      "~n   Key: ~p", [Key]),
117	    case ets:lookup(?TABLE, Key) of
118		[{Key, Val}] ->
119		    p("loop -> lookup: ~p", [Val]),
120		    From ! {lookup, self(), {value, Val}};
121		_ ->
122		    p("loop -> lookup unsuccessful"),
123		    From ! {lookup, self(), false}
124	    end;
125	{stop, Parent, _} ->
126	    p("loop -> received stop request"),
127	    ets:delete(?TABLE),
128	    global:unregister_name(?SERVER),
129	    Parent ! {stop, self(), ok},
130	    exit(normal);
131
132	{'EXIT', Parent, Reason} when is_pid(Parent) ->
133	    p("loop -> received exit signal from parent"
134	      "~n   Reason: ~p", [Reason]),
135	    exit(Reason);
136
137	{UnknownRequest, Parent, UnknownData} when is_pid(Parent) ->
138	    p("loop -> received unknown request when"
139	      "~n   UnknownRequest: ~p"
140	      "~n   UnknownData:    ~p", [UnknownRequest, UnknownData]),
141	    Error = {error, {unknown_request, {UnknownRequest, UnknownData}}},
142	    Parent ! {UnknownRequest, self(), Error};
143
144	{Request, From, Data} when is_pid(From) ->
145	    p("loop -> received request from unknown when"
146	      "~n   Request: ~p"
147	      "~n   From:    ~p"
148	      "~n   Data:    ~p", [Request, From, Data]),
149	    Error = {error, {unknown_request, {Request, Data}}},
150	    Parent ! {Request, self(), Error};
151
152	Crap ->
153	    p("loop -> received crap: "
154	      "~n   Crap:   ~p"
155	      "~nwhen"
156	      "~n   Parent: ~p", [Crap, Parent]),
157	    ok
158    end,
159    loop(Parent).
160
161
162p(F) ->
163    p(F, []).
164
165p(F, A) ->
166    p(get(dbg), F, A).
167
168p(true, F, A) ->
169    io:format("~w:~p:" ++ F ++ "~n", [?MODULE, self()|A]);
170p(_, _, _) ->
171    ok.
172
173