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