1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2000-2019. 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: A fun implementation of user callbacks 24%%---------------------------------------------------------------------- 25 26-module(megaco_mess_user_test). 27 28-behaviour(megaco_user). 29 30-export([ 31 handle_connect/2, handle_connect/3, 32 handle_disconnect/3, 33 handle_syntax_error/3, handle_syntax_error/4, 34 handle_message_error/3, handle_message_error/4, 35 handle_trans_request/3, handle_trans_request/4, 36 handle_trans_long_request/3, handle_trans_long_request/4, 37 handle_trans_reply/4, handle_trans_reply/5, 38 handle_trans_ack/4, handle_trans_ack/5, 39 handle_unexpected_trans/3, handle_unexpected_trans/4, 40 handle_trans_request_abort/4, handle_trans_request_abort/5, 41 handle_segment_reply/5, handle_segment_reply/6 42 ]). 43 44-export([ 45 start_proxy/0, 46 stop_proxy/0, 47 apply_proxy/1, 48 reply/3, 49 50 start_transport/2, 51 loop_transport/1, % Internal only 52 send_message/2, 53 resend_message/2 54 ]). 55 56-include("megaco_test_lib.hrl"). 57-define(SERVER, ?MODULE). 58 59start_proxy() -> 60 yes = global:register_name(?SERVER, self()), 61 Pid = megaco_test_lib:proxy_start(?MODULE), 62 put(?MODULE, Pid), 63 Pid. 64 65stop_proxy() -> 66 global:unregister_name(?SERVER), 67 Pid = erase(?MODULE), 68 unlink(Pid), 69 exit(Pid, shutdown). 70 71whereis_proxy() -> 72 case get(?MODULE) of 73 undefined -> 74 exit(no_server, ?MODULE); 75 Pid when is_pid(Pid) -> 76 Pid 77 end. 78 79apply_proxy(Fun) -> 80 Pid = whereis_proxy(), 81 ?APPLY(Pid, Fun), 82 ok. 83 84reply(Mod, Line, Fun) when is_function(Fun) -> 85 receive 86 {?MODULE, Pid, UserCallback} -> 87 UserReply = Fun(UserCallback), 88 Pid ! {?MODULE, self(), UserReply}, 89 UserReply%% ; 90 %% Other -> 91 %% megaco_test_lib:error(Other, Mod, Line), 92 %% {error, Other} 93 after 10000 -> 94 megaco_test_lib:error(timeout, Mod, Line), 95 {error, timeout} 96 end. 97 98call(UserCallback) -> 99 Request = {?MODULE, self(), UserCallback}, 100 case global:whereis_name(?SERVER) of 101 undefined -> 102 exit({no_server, ?SERVER, Request}); 103 Pid when is_pid(Pid) -> 104 ?LOG("call[~p] -> bang request: " 105 "~n ~p" 106 "~n", [Pid, Request]), 107 Pid ! Request, 108 call_await_reply(Pid) 109 end. 110 111call_await_reply(Pid) -> 112 receive 113 {?MODULE, Pid, UserReply} = _Reply -> 114 case UserReply of 115 {ok, Good} -> Good; 116 {error, Bad} -> exit(Bad) 117 end; 118 {'EXIT', Pid, Reason} = Bad -> 119 ?LOG("receive test case exit: ~p~n", [Bad]), 120 exit(Reason); 121 {'EXIT', _, _Reason} = Bad -> 122 ?LOG("receive unknown exit: ~p~n", [Bad]), 123 call_await_reply(Pid); 124 Bad -> 125 ?LOG("receive other: ~p~n", [Bad]), 126 exit(Bad) 127 end. 128 129%%---------------------------------------------------------------------- 130%% Megaco user callback 131%%---------------------------------------------------------------------- 132 133%% -- handle_connect/2 -- 134 135handle_connect(ConnHandle, ProtocolVersion) -> 136%% io:format("~p~p[~p]: handle_connect -> entry with" 137%% "~n ConnHandle: ~p" 138%% "~n ProtocolVersion: ~p" 139%% "~n", 140%% [self(), ?MODULE, ?LINE, ConnHandle, ProtocolVersion]), 141 call({connect, ConnHandle, ProtocolVersion, []}). 142 143handle_connect(ConnHandle, ProtocolVersion, Extra) -> 144%% io:format(user,"~p~p[~p]: handle_connect -> entry with" 145%% "~n ConnHandle: ~p" 146%% "~n ProtocolVersion: ~p" 147%% "~n Extra: ~p" 148%% "~n", 149%% [self(), ?MODULE, ?LINE, ConnHandle, ProtocolVersion, Extra]), 150 call({connect, ConnHandle, ProtocolVersion, [Extra]}). 151 152 153%% -- handle_disconnect/3 -- 154 155handle_disconnect(ConnHandle, ProtocolVersion, Reason) -> 156 %% io:format("~w:~w:~p:handle_disconnect -> entry with" 157 %% "~n ConnHandle: ~p" 158 %% "~n ProtocolVersion: ~p" 159 %% "~n Reason: ~p" 160 %% "~n", 161 %% [?MODULE, ?LINE, self(), ConnHandle, ProtocolVersion, Reason]), 162 call({disconnect, ConnHandle, ProtocolVersion, [Reason]}). 163 164 165%% -- handle_syntax_error/3,4 -- 166 167handle_syntax_error(ReceiveHandle, ProtocolVersion, ErrorDescriptor) -> 168 call({syntax_error, ReceiveHandle, ProtocolVersion, [ErrorDescriptor]}). 169 170handle_syntax_error(ReceiveHandle, ProtocolVersion, ErrorDescriptor, Extra) -> 171 call({syntax_error, ReceiveHandle, ProtocolVersion, [ErrorDescriptor, Extra]}). 172 173 174%% -- handle_message_error/3,4 -- 175 176handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor) -> 177 call({message_error, ConnHandle, ProtocolVersion, [ErrorDescriptor]}). 178 179handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Extra) -> 180 call({message_error, ConnHandle, ProtocolVersion, [ErrorDescriptor, Extra]}). 181 182 183%% -- handle_trans_request/3,4 -- 184 185handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests) -> 186 call({request, ConnHandle, ProtocolVersion, [ActionRequests]}). 187 188handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests, Extra) -> 189 call({request, ConnHandle, ProtocolVersion, [ActionRequests, Extra]}). 190 191%% -- handle_trans_long_request/3,4 -- 192 193handle_trans_long_request(ConnHandle, ProtocolVersion, RequestData) -> 194 call({long_request, ConnHandle, ProtocolVersion, [RequestData]}). 195 196handle_trans_long_request(ConnHandle, ProtocolVersion, RequestData, Extra) -> 197 call({long_request, ConnHandle, ProtocolVersion, [RequestData, Extra]}). 198 199 200%% -- handle_trans_relpy/4,5 -- 201 202handle_trans_reply(ConnHandle, ProtocolVersion, UserReply, UserData) -> 203 call({reply, ConnHandle, ProtocolVersion, [UserReply, UserData]}). 204 205handle_trans_reply(ConnHandle, ProtocolVersion, UserReply, UserData, Extra) -> 206 call({reply, ConnHandle, ProtocolVersion, [UserReply, UserData, Extra]}). 207 208 209%% -- handle_trans_relpy/4,5 -- 210 211handle_trans_ack(ConnHandle, ProtocolVersion, AckStatus, AckData) -> 212 call({ack, ConnHandle, ProtocolVersion, [AckStatus, AckData]}). 213 214handle_trans_ack(ConnHandle, ProtocolVersion, AckStatus, AckData, Extra) -> 215 call({ack, ConnHandle, ProtocolVersion, [AckStatus, AckData, Extra]}). 216 217 218%% -- handle_unexpected_trans/3,4 -- 219 220handle_unexpected_trans(ConnHandle, ProtocolVersion, Trans) -> 221 call({unepected_trans, ConnHandle, ProtocolVersion, [Trans]}). 222 223handle_unexpected_trans(ConnHandle, ProtocolVersion, Trans, Extra) -> 224 call({unepected_trans, ConnHandle, ProtocolVersion, [Trans, Extra]}). 225 226 227%% -- handle_trans_request_abort/4,5 -- 228 229handle_trans_request_abort(ConnHandle, ProtocolVersion, TransId, Pid) -> 230 call({request_abort, ConnHandle, ProtocolVersion, [TransId, Pid]}). 231 232handle_trans_request_abort(ConnHandle, ProtocolVersion, TransId, Pid, Extra) -> 233 call({request_abort, ConnHandle, ProtocolVersion, [TransId, Pid, Extra]}). 234 235 236%% -- handle_segment_reply/5,6 -- 237 238handle_segment_reply(ConnHandle, ProtocolVersion, TransId, SN, SC) -> 239 call({segment_reply, ConnHandle, ProtocolVersion, [TransId, SN, SC]}). 240 241handle_segment_reply(ConnHandle, ProtocolVersion, TransId, SN, SC, Extra) -> 242 call({segment_reply, ConnHandle, ProtocolVersion, [TransId, SN, SC, Extra]}). 243 244 245%%---------------------------------------------------------------------- 246%% The ultimate Megaco transport callback 247%%---------------------------------------------------------------------- 248 249start_transport(MgReceiveHandle, MgcReceiveHandle) -> 250 MgControlPid = spawn_link(?MODULE, loop_transport, [self()]), 251 MgSendHandle = {MgcReceiveHandle, MgControlPid}, 252 MgcControlPid = spawn_link(?MODULE, loop_transport, [self()]), 253 MgcSendHandle = {MgReceiveHandle, MgcControlPid}, 254 SendHandle = {MgSendHandle, MgcSendHandle}, 255 {ok, MgControlPid, SendHandle}. 256 257loop_transport(Parent) -> 258 receive 259 {'EXIT', _Pid, Reason} = Error -> 260 ok = io:format("transport stopped: ~p~n", [{Parent, Error}]), 261 exit(Reason) 262 end. 263 264send_message(Handles, Bin) -> 265 ?LOG("send_message -> entry with" 266 "~n Handles: ~p" 267 "~n", [Handles]), 268 case megaco_tc_controller:lookup(allow_send_message) of 269 {value, ok} -> 270 do_send_message(Handles, Bin); 271 {value, {fail, Reason}} -> 272 {error, Reason}; 273 {value, {cancel, Reason}} -> 274 {cancel, Reason}; 275 {value, {skip, Result}} -> 276 Result; 277 false -> 278 do_send_message(Handles, Bin) 279 end. 280 281resend_message(Handles, Bin) -> 282 ?LOG("resend_message -> entry with" 283 "~n Handles: ~p" 284 "~n", [Handles]), 285 case megaco_tc_controller:lookup(allow_resend_message) of 286 {value, ok} -> 287 do_send_message(Handles, Bin); 288 {value, {fail, Reason}} -> 289 {error, Reason}; 290 {value, {cancel, Reason}} -> 291 {cancel, Reason}; 292 {value, {skip, Result}} -> 293 Result; 294 false -> 295 do_send_message(Handles, Bin) 296 end. 297 298do_send_message({{RH, Pid} = LocalSendHandle, RemoteSendHandle}, Bin) -> 299 ?LOG("do_send_message -> entry with" 300 "~n RH: ~p" 301 "~n Pid: ~p" 302 "~n RemoteSendHandle: ~p" 303 "~n", [RH, Pid, RemoteSendHandle]), 304 SwappedSendHandle = {RemoteSendHandle, LocalSendHandle}, 305 case megaco_tc_controller:lookup(extra_transport_info) of 306 {value, Extra} -> 307 megaco:receive_message(RH, Pid, SwappedSendHandle, Bin, Extra); 308 _ -> 309 megaco:receive_message(RH, Pid, SwappedSendHandle, Bin) 310 end. 311