1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1999-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%%
24%% Purpose:
25%%      Interface the TPKT (TCP/IP) transport module for Megaco/H.248
26%%
27%%-----------------------------------------------------------------
28-module(megaco_tcp).
29
30-behaviour(gen_server).
31
32
33%%-----------------------------------------------------------------
34%% Include files
35%%-----------------------------------------------------------------
36-include_lib("megaco/include/megaco.hrl").
37-include_lib("megaco/src/tcp/megaco_tcp.hrl").
38-include_lib("megaco/src/app/megaco_internal.hrl").
39
40
41-define(d1(F, A), ?d("~p " ++ F, [self()|A])).
42-define(d2(F),    ?d1(F, [])).
43
44
45%%-----------------------------------------------------------------
46%% External exports
47%%-----------------------------------------------------------------
48-export([
49	 start_transport/0, %% Start TPKT transport service
50	 stop_transport/1,  %% Stop TPKT transport service
51	 listen/2,          %% Starts a new listener socket
52	 connect/2,         %% Used on client side to connect server
53	 socket/1,          %% Returns the inet socket
54	 send_message/2,    %% Used to send data on connection
55	 block/1,           %% Used to block the socket for incomming
56	                    %% messages
57	 unblock/1,         %% Used to unblock the node
58	 close/1,           %% Used on both sides to close connection
59
60	 upgrade_receive_handle/2
61	]).
62
63%% Statistics exports
64-export([
65	 get_stats/0, get_stats/1, get_stats/2,
66	 reset_stats/0, reset_stats/1
67	]).
68
69
70%%-----------------------------------------------------------------
71%% Internal exports
72%%-----------------------------------------------------------------
73-export([
74	 start_link/1,       %% Start TCP/IP net server
75	 init/1,             %%
76	 terminate/2,
77	 handle_call/3,
78	 handle_cast/2,
79	 handle_info/2,
80	 code_change/3,
81	 start_connection/2
82	]).
83
84
85%%-----------------------------------------------------------------
86%% Server state record
87%%-----------------------------------------------------------------
88-record(state, {supervisor_pid, linkdb}).
89
90
91%%-----------------------------------------------------------------
92%% External interface functions
93%%-----------------------------------------------------------------
94
95%%-----------------------------------------------------------------
96%% Func: get_stats/0, get_stats/1, get_stats/2
97%% Description: Retreive statistics (counters) for TCP
98%%-----------------------------------------------------------------
99get_stats() ->
100    megaco_stats:get_stats(megaco_tcp_stats).
101
102get_stats(Socket) ->
103    megaco_stats:get_stats(megaco_tcp_stats, Socket).
104
105get_stats(Socket, Counter) ->
106    megaco_stats:get_stats(megaco_tcp_stats, Socket, Counter).
107
108
109%%-----------------------------------------------------------------
110%% Func: reset_stats/0, reaet_stats/1
111%% Description: Reset statistics (counters) for TCP
112%%-----------------------------------------------------------------
113reset_stats() ->
114    megaco_stats:reset_stats(megaco_tcp_stats).
115
116reset_stats(Socket) ->
117    megaco_stats:reset_stats(megaco_tcp_stats, Socket).
118
119
120%%-----------------------------------------------------------------
121%% Func: start_transport/0
122%% Description: Starts the TPKT transport service
123%%-----------------------------------------------------------------
124start_transport() ->
125    ?d2("start_transport -> entry"),
126    (catch megaco_stats:init(megaco_tcp_stats)),
127    megaco_tcp_sup:start_link().
128
129
130%%-----------------------------------------------------------------
131%% Func: stop_transport/1, 2
132%% Description: Stop the TPKT transport service
133%%-----------------------------------------------------------------
134stop_transport(Pid) ->
135    (catch unlink(Pid)),
136    stop_transport(Pid, shutdown).
137
138stop_transport(Pid, Reason) ->
139    ?d1("stop_transport -> entry with"
140	"~n   Pid:    ~p"
141	"~n   Reason: ~p", [Pid, Reason]),
142    exit(Pid, Reason).
143
144
145%%-----------------------------------------------------------------
146%% Func: listen/2
147%% Description: Starts new TPKT listener sockets
148%%-----------------------------------------------------------------
149listen(SupPid, Parameters) ->
150    ?d1("listen -> entry with"
151	"~n   SupPid:     ~p"
152	"~n   Parameters: ~p", [SupPid, Parameters]),
153    ProcList = supervisor:which_children(SupPid),
154    case lists:keysearch(megaco_tcp, 1, ProcList) of
155	{value, {_Name, Pid, _Type, _Modules}} ->
156	    ?d1("listen -> found listener: "
157		"~n   Pid: ~p", [Pid]),
158	    call(Pid, {add_listener, Parameters});
159	false ->
160	    {error, no_tcp_server}
161    end.
162
163
164%%-----------------------------------------------------------------
165%% Func: connect
166%% Description: Function is used when opening an TCP socket
167%%              at the MG side when trying to connect an MGC
168%%-----------------------------------------------------------------
169connect(SupPid, Parameters) ->
170    ?d1("connect -> entry with"
171	"~n   SupPid:     ~p"
172	"~n   Parameters: ~p", [SupPid, Parameters]),
173    Mand = [host, port, receive_handle],
174    case parse_options(Parameters, #megaco_tcp{}, Mand) of
175	{ok, Rec} ->
176
177	    ?d1("connect -> options parsed: "
178		"~n   Rec: ~p", [Rec]),
179
180	    #megaco_tcp{host    = Host,
181			port    = Port,
182			options = Options} = Rec,
183
184	    IpOpt = [binary, {packet, tpkt}, {active, once} | Options],
185
186            %%------------------------------------------------------
187            %% Connect the other side
188	    case (catch gen_tcp:connect(Host, Port, IpOpt)) of
189		{ok, Socket} ->
190		    ?d1("connect -> connected: "
191			"~n   Socket: ~p", [Socket]),
192                    %%----------------------------------------------
193                    %% Socket up start a new control process
194		    Rec2 = Rec#megaco_tcp{socket = Socket},
195		    case start_connection(SupPid, Rec2) of
196			{ok, Pid} ->
197			    ?d1("connect -> connection started: "
198				"~n   Pid: ~p", [Pid]),
199			    gen_tcp:controlling_process(Socket, Pid),
200			    ?d2("connect -> control transferred"),
201			    {ok, Socket, Pid};
202			{error, Reason} ->
203			    ?d1("connect -> failed starting connection: "
204				"~n   Reason: ~p", [Reason]),
205			    {error, Reason}
206		    end;
207
208		{error, Reason} ->
209		    ?d1("connect -> failed connecting: "
210			"~n   Reason: ~p", [Reason]),
211		    Error = {error, {gen_tcp_connect, Reason}},
212		    ?tcp_debug(Rec, "tcp connect failed", [Error]),
213		    Error;
214
215		{'EXIT', _Reason} = Exit ->
216		    ?d1("connect -> connect exited: "
217			"~n   Exit: ~p", [Exit]),
218		    Error = {error, {gen_tcp_connect, Exit}},
219		    ?tcp_debug(Rec, "tcp connect failed", [Error]),
220		    Error
221
222	    end;
223
224	{error, _Reason} = Error ->
225	    ?d1("connect -> failed parsing options: "
226		"~n   Error: ~p", [Error]),
227	    ?tcp_debug(#megaco_tcp{}, "tcp connect failed",
228		       [Error, {options, Parameters}]),
229	    Error
230    end.
231
232
233%%-----------------------------------------------------------------
234%% Func: send_message
235%% Description: Function is used for sending data on the TCP socket
236%%-----------------------------------------------------------------
237send_message(Socket, Data) ->
238    ?d1("send_message -> entry with"
239	"~n   Socket:     ~p"
240	"~n   size(Data): ~p", [Socket, sz(Data)]),
241    {Size, NewData} = add_tpkt_header(Data),
242    Res = gen_tcp:send(Socket, NewData),
243    case Res of
244	ok ->
245	    incNumOutMessages(Socket),
246	    incNumOutOctets(Socket, Size);
247	_ ->
248	    ok
249    end,
250    Res.
251
252-ifdef(megaco_debug).
253sz(Bin) when is_binary(Bin) ->
254    size(Bin);
255sz(List) when is_list(List) ->
256    length(List).
257-endif.
258
259
260%%-----------------------------------------------------------------
261%% Func: block
262%% Description: Function is used for blocking incomming messages
263%%              on the TCP socket
264%%-----------------------------------------------------------------
265block(Socket) ->
266    ?tcp_debug({socket, Socket}, "tcp block", []),
267    inet:setopts(Socket, [{active, false}]).
268
269
270%%-----------------------------------------------------------------
271%% Func: unblock
272%% Description: Function is used for blocking incomming messages
273%%              on the TCP socket
274%%-----------------------------------------------------------------
275unblock(Socket) ->
276    ?tcp_debug({socket, Socket}, "tcp unblock", []),
277    inet:setopts(Socket, [{active, once}]).
278
279
280%%-----------------------------------------------------------------
281%% Func: close
282%% Description: Function is used for closing the TCP socket
283%%-----------------------------------------------------------------
284close(Socket) ->
285    ?tcp_debug({socket, Socket}, "tcp close", []),
286    gen_tcp:close(Socket).
287
288
289%%-----------------------------------------------------------------
290%% Func: socket
291%% Description: Returns the inet socket
292%%-----------------------------------------------------------------
293socket(Socket) ->
294    Socket.
295
296upgrade_receive_handle(Pid, NewHandle)
297  when is_pid(Pid) andalso is_record(NewHandle, megaco_receive_handle) ->
298    megaco_tcp_connection:upgrade_receive_handle(Pid, NewHandle).
299
300
301%%-----------------------------------------------------------------
302%% Internal Interface functions
303%%-----------------------------------------------------------------
304%%-----------------------------------------------------------------
305%% Func: start_link/1
306%% Description: Starts the net server
307%%-----------------------------------------------------------------
308start_link(Args) ->
309    gen_server:start_link(?MODULE, Args, []).
310
311
312%%-----------------------------------------------------------------
313%% Func: start_connection
314%% Description: Function is used for starting up a connection
315%%              process
316%%-----------------------------------------------------------------
317start_connection(SupPid, #megaco_tcp{socket = Socket} = TcpRec) ->
318    ?d1("start_connection -> entry with"
319	"~n   SupPid: ~p"
320	"~n   Socket: ~p", [SupPid, Socket]),
321
322    case connection_sup(SupPid) of
323	{ok, ConnSupPid} ->
324	    ?d1("start_connection -> found connection supervisor: "
325		"~n   ConnSupPid: ~p", [ConnSupPid]),
326	    ?tcp_debug(TcpRec, "tcp connect", []),
327	    case create_connection(ConnSupPid, TcpRec) of
328		{ok, Pid} ->
329		    ?d1("start_connection -> started: "
330			"~n   Pid: ~p", [Pid]),
331		    ?tcp_debug(TcpRec, "connect handler started", [Pid]),
332		    create_snmp_counters(Socket),
333		    {ok, Pid};
334		{error, Reason} ->
335		    ?d1("start_connection -> failed starting: "
336			"~n   Reason: ~p", [Reason]),
337		    Error = {error, {controlling_process_not_started, Reason}},
338		    ?tcp_debug(TcpRec, "tcp connect failed", [Error]),
339		    Error
340	    end;
341	{error, _Reason} ->
342	    ?d2("start_connection -> could not find connection supervisor"),
343	    Error = {error, no_connection_supervisor},
344	    ?tcp_debug(TcpRec, "tcp connect failed", [Error]),
345	    Error
346    end.
347
348connection_sup(Pid) ->
349    megaco_tcp_sup:which_connection_sup(Pid).
350
351create_connection(Pid, Rec) ->
352    megaco_tcp_connection_sup:start_child(Pid, Rec).
353
354create_snmp_counters(Socket) ->
355    Counters = [medGwyGatewayNumInMessages,
356                medGwyGatewayNumInOctets,
357                medGwyGatewayNumOutMessages,
358                medGwyGatewayNumOutOctets,
359                medGwyGatewayNumErrors],
360    create_snmp_counters(Socket, Counters).
361
362create_snmp_counters(_Socket, []) ->
363    ok;
364create_snmp_counters(Socket, [Counter|Counters]) ->
365    Key = {Socket, Counter},
366    ets:insert(megaco_tcp_stats, {Key, 0}),
367    create_snmp_counters(Socket, Counters).
368
369
370%%-----------------------------------------------------------------
371%% Server functions
372%%-----------------------------------------------------------------
373%%-----------------------------------------------------------------
374%% Func: init/1
375%% Description: Init funcion for the supervisor
376%%-----------------------------------------------------------------
377init({SupPid, _}) ->
378    process_flag(trap_exit, true),
379    {ok, #state{supervisor_pid = SupPid}}.
380
381%%-----------------------------------------------------------------
382%% Func: terminate/1
383%% Description: Termination function for the generic server
384%%-----------------------------------------------------------------
385terminate(_Reason, _State) ->
386    ok.
387
388
389%%-----------------------------------------------------------------
390%% Internal Functions
391%%-----------------------------------------------------------------
392
393%%-----------------------------------------------------------------
394%% Func: start_tcp_listener/2
395%% Description: Function which parses the list of transport layers
396%%              to start
397%%-----------------------------------------------------------------
398start_tcp_listener(P, State) ->
399    ?d1("start_tcp_listener -> entry with"
400	"~n   P: ~p", [P]),
401    case setup(State#state.supervisor_pid, P) of
402	{ok, Pid, Data} ->
403	    ?d1("start_tcp_listener -> setup ok"
404		"~n   Pid:  ~p"
405		"~n   Data: ~p", [Pid, Data]),
406	    link(Pid),
407	    {reply, ok,
408	     State#state{linkdb=[{Pid, Data} | State#state.linkdb]}};
409	{error, Reason} ->
410	    ?d1("start_tcp_listener -> setup failed"
411		"~n   Reason: ~p", [Reason]),
412	    {reply, {error, {could_not_start_listener, Reason}}, State}
413    end.
414
415
416%%-----------------------------------------------------------------
417%% Func: handle_call/3
418%% Description: Handling call messages (really just garbage)
419%%-----------------------------------------------------------------
420handle_call({add_listener, Parameters}, _From, State) ->
421    ?d1("handle_call(add_listener) -> entry with"
422	"~n   Parameters: ~p", [Parameters]),
423    start_tcp_listener(Parameters, State);
424handle_call(Req, From, State) ->
425    warning_msg("received unexpected request from ~p: "
426		"~n~w", [From, Req]),
427    {noreply, State}.
428
429
430%%------------------------------------------------------------
431%% Func: handle_cast/2
432%% Description: Handling cast messages (really just garbage)
433%%------------------------------------------------------------
434handle_cast(Msg, State) ->
435    warning_msg("received unexpected message: "
436		"~n~w", [Msg]),
437    {noreply,  State}.
438
439
440%%-----------------------------------------------------------------
441%% Func: handle_info/2
442%% Description: Handling non call/cast messages, eg exit messages
443%%-----------------------------------------------------------------
444handle_info({'EXIT', Pid, Reason}, State) when is_pid(Pid) ->
445    %% Accept process died
446    NewState = resetup(Pid, Reason, State),
447    {noreply, NewState};
448handle_info(Info, State) ->
449    warning_msg("received unexpected info: "
450		"~n~w", [Info]),
451    {noreply,  State}.
452
453
454%%-----------------------------------------------------------------
455%% Func: code_change/3
456%% Descrition: Handles code change messages during upgrade.
457%%-----------------------------------------------------------------
458code_change(_Vsn, State, _Extra) ->
459    {ok, State}.
460
461
462%%-----------------------------------------------------------------
463%% Internal functions
464%%-----------------------------------------------------------------
465%%-----------------------------------------------------------------
466%% Func: setup/2
467%% Description: Function is used when setting up an TCP listen
468%%              socket in the MGC
469%%-----------------------------------------------------------------
470setup(SupPid, Options) ->
471    ?d1("setup -> entry with"
472	"~n   SupPid:  ~p"
473	"~n   Options: ~p", [SupPid, Options]),
474    Mand = [port, receive_handle],
475    case parse_options(Options, #megaco_tcp{}, Mand) of
476	{ok, TcpRec} ->
477
478	    ?d1("setup -> options parsed"
479		"~n   TcpRec: ~p", [TcpRec]),
480
481            %%------------------------------------------------------
482            %% Setup the listen socket
483	    IpOpts = [binary, {packet, tpkt}, {active, once},
484		      {reuseaddr, true} | TcpRec#megaco_tcp.options],
485	    case catch gen_tcp:listen(TcpRec#megaco_tcp.port, IpOpts) of
486		{ok, Listen} ->
487
488		    ?d1("setup -> listen ok"
489			"~n   Listen: ~p", [Listen]),
490
491	            %%-----------------------------------------------
492	            %% Startup the accept process that will wait for
493	            %% connect attempts
494		    case start_accept(SupPid, TcpRec, Listen) of
495			{ok, Pid} ->
496
497			    ?d1("setup -> accept process started"
498				"~n   Pid: ~p", [Pid]),
499
500			    ?tcp_debug(TcpRec, "tcp listen setup", []),
501			    {ok, Pid, {TcpRec, Listen}};
502			{error, _Reason} = Error ->
503			    ?d1("setup -> failed starting accept process"
504				"~n   Error: ~p", [Error]),
505			    ?tcp_debug(TcpRec, "tcp listen setup failed",
506				       [Error]),
507			    Error
508		    end;
509		{error, Reason} ->
510		    ?d1("setup -> listen failed"
511			"~n   Reason: ~p", [Reason]),
512		    Error = {error, {gen_tcp_listen, Reason}},
513		    ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]),
514		    Error;
515		{'EXIT', _Reason} = Exit ->
516		    ?d1("setup -> listen exited"
517			"~n   Exit: ~p", [Exit]),
518		    Error = {error, {gen_tcp_listen, Exit}},
519		    ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]),
520		    Error
521	    end;
522	{error, _Reason} = Error ->
523	    ?d1("setup -> failed parsing options"
524		"~n   Error: ~p", [Error]),
525	    ?tcp_debug(#megaco_tcp{}, "tcp listen setup failed",
526		       [Error, {options, Options}]),
527	    Error
528    end.
529
530
531%%-----------------------------------------------------------------
532%% Func: resetup
533%% Description: Function is used when restarting the accept process
534%%              if it died for some reason.
535%%-----------------------------------------------------------------
536
537resetup(Pid, Reason, State) ->
538    ?d1("resetup -> entry with"
539	"~n   Pid:    ~p"
540	"~n   Reason: ~p", [Pid, Reason]),
541    case lists:keysearch(Pid, 1, State#state.linkdb) of
542	{value, {Pid, {TcpRec, Listener}}} ->
543	    ?d1("resetup -> found accept process: "
544		"~n   TcpRec:   ~p"
545		"~n   Listener: ~p", [TcpRec, Listener]),
546	    ?tcp_debug(TcpRec, "tcp listen resetup", [{error, Reason}]),
547	    unlink(Pid),
548	    warning_msg("received unexpected 'EXIT' signal "
549			"from accept process ~p: "
550			"~n~w", [Pid, Reason]),
551	    case start_accept(State#state.supervisor_pid, TcpRec, Listener) of
552		{ok, NewPid} ->
553		    ?d1("resetup -> start new accept process ok: "
554			"~n   NewPid: ~p", [NewPid]),
555		    link(NewPid),
556		    NewList = lists:keyreplace(Pid, 1, State#state.linkdb,
557					       {NewPid, {TcpRec, Listener}}),
558		    State#state{linkdb = NewList};
559		{error, Reason} ->
560		    ?d1("resetup -> failed starting new accept process: "
561			"~n   :Reason ~p", [Reason]),
562		    ?tcp_debug(TcpRec,
563			       "tcp listen resetup failed", [{error, Reason}]),
564		    State
565	    end;
566	false ->
567	    warning_msg("received unexpected 'EXIT' signal from ~p: "
568			"~n~w", [Pid, Reason]),
569	    State
570    end.
571
572
573%%-----------------------------------------------------------------
574%% Func: start_accept
575%% Description: Function is used for starting up an TCP accept
576%%              process
577%%-----------------------------------------------------------------
578start_accept(SupPid, TcpRec, Listen) ->
579    ?d1("start_accept -> entry with"
580	"~n   SupPid: ~p"
581	"~n   TcpRec: ~p"
582	"~n   Reason: ~p", [SupPid, TcpRec, Listen]),
583    case accept_sup(SupPid) of
584	{ok, AcceptSupPid} ->
585	    ?d1("start_accept -> found accept supervisor"
586		"~n   AcceptSupPid: ~p", [AcceptSupPid]),
587	    case create_acceptor(AcceptSupPid, TcpRec, SupPid, Listen) of
588		{ok, Pid} ->
589		    ?d1("start_accept -> accept process started"
590			"~n   Pid: ~p", [Pid]),
591		    {ok, Pid};
592		{error, Reason} ->
593		    ?d1("start_accept -> failed starting accept process: "
594			"~n   Reason: ~p", [Reason]),
595		    {error, {accept_not_started, Reason}}
596	    end;
597	{error, Reason} ->
598	    ?d1("start_accept -> could not find acceept supervisor: "
599		"~n   Reason: ~p", [Reason]),
600	    {error, {no_tcp_accept_sup, Reason}}
601    end.
602
603accept_sup(Pid) ->
604    megaco_tcp_sup:which_accept_sup(Pid).
605
606create_acceptor(Pid, Rec, TopSup, Listen) ->
607    megaco_tcp_accept_sup:start_child(Pid, Rec, TopSup, Listen).
608
609
610%%-----------------------------------------------------------------
611%% Func: add_tpkt_header
612%% Description: Function is used to add the TPKT header
613%%-----------------------------------------------------------------
614add_tpkt_header(Data) when is_binary(Data) ->
615    L = size(Data) + 4,
616    {L, [3, 0, ((L) bsr 8) band 16#ff, (L) band 16#ff ,Data]};
617add_tpkt_header(IOList) when is_list(IOList) ->
618    Binary = list_to_binary(IOList),
619    L = size(Binary) + 4,
620    {L, [3, 0, ((L) bsr 8) band 16#ff, (L) band 16#ff , Binary]}.
621
622%%-----------------------------------------------------------------
623%% Func: parse_options
624%% Description: Function that parses the options sent to the TCP
625%%              module.
626%%-----------------------------------------------------------------
627parse_options([{Tag, Val} | T], TcpRec, Mand) ->
628    ?d1("parse_options -> entry with"
629	"~n   Tag: ~p"
630	"~n   Val: ~p", [Tag, Val]),
631    Mand2 = Mand -- [Tag],
632    case Tag of
633	port ->
634	    parse_options(T, TcpRec#megaco_tcp{port = Val}, Mand2);
635	host ->
636	    parse_options(T, TcpRec#megaco_tcp{host = Val}, Mand2);
637	tcp_options when is_list(Val) ->
638	    parse_options(T, TcpRec#megaco_tcp{options = Val}, Mand2);
639	receive_handle ->
640	    parse_options(T, TcpRec#megaco_tcp{receive_handle = Val}, Mand2);
641	module when is_atom(Val) ->
642	    parse_options(T, TcpRec#megaco_tcp{module = Val}, Mand2);
643	serialize when (Val =:= true) orelse (Val =:= false) ->
644	    parse_options(T, TcpRec#megaco_tcp{serialize = Val}, Mand2);
645        Bad ->
646	    ?d1("parse_options -> bad option: "
647		"~n   Tag: ~p", [Tag]),
648	    {error, {bad_option, Bad}}
649    end;
650parse_options([], TcpRec, []) ->
651    ?d2("parse_options -> done"),
652    {ok, TcpRec};
653parse_options([], _TcpRec, Mand) ->
654    ?d1("parse_options -> entry with"
655	"~n   Mand: ~p", [Mand]),
656    {error, {missing_options, Mand}};
657parse_options(BadList, _TcpRec, _Mand) ->
658    ?d1("parse_options -> entry with"
659	"~n   BadList: ~p", [BadList]),
660    {error, {bad_option_list, BadList}}.
661
662
663%%-----------------------------------------------------------------
664%% Func: incNumOutMessages/1, incNumOutOctets/2, incNumErrors/1
665%% Description: SNMP counter increment functions
666%%
667%%-----------------------------------------------------------------
668incNumOutMessages(Socket) ->
669    incCounter({Socket, medGwyGatewayNumOutMessages}, 1).
670
671incNumOutOctets(Socket, NumOctets) ->
672    incCounter({Socket, medGwyGatewayNumOutOctets}, NumOctets).
673
674incCounter(Key, Inc) ->
675    ets:update_counter(megaco_tcp_stats, Key, Inc).
676
677% incNumErrors(Socket) ->
678%     ets:update_counter(megaco_tcp_stats,
679% 		       {Socket, medGwyGatewayNumErrors}, 1).
680
681
682%%-----------------------------------------------------------------
683
684
685warning_msg(F, A) ->
686    ?megaco_warning("TCP server: " ++ F, A).
687
688%% error_msg(F, A) ->
689%%     ?megaco_error("TCP server: " ++ F, A).
690
691
692call(Pid, Req) ->
693    gen_server:call(Pid, Req, infinity).
694