summaryrefslogtreecommitdiff
path: root/tcpserv.erl
blob: d76dcb8f6cc5aa46de1a95a2585bd6f369bdc7ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
%%%-------------------------------------------------------------------
%%% @author Joe Zhao
%%% @copyright (C) 2014, <COMPANY>
%%% @doc
%%% TCP server for socket connections
%%% One listenners of ports
%%% Spawns one receiver and one sender for different socket.
%%% @end
%%% Created : 27. 四月 2014 20:52
%%%-------------------------------------------------------------------
-module(tcpserv).
-author("Joe Zhao").

-compile([debug_info,export_all]).

-define(TCP_OPTIONS,[list, {packet, 1},  {active, true}]).
-define(DLYTIME,1000).
%% API
%%-export([]).

lsockinit() -> ok.

do_loop(Sock,Pid,N) ->
  receive
    {tcp,Sock,Data} ->
      io:format("~p:\n ~p\n",[N,Data]),
      manip_msg(Pid,Data),
      do_loop(Sock,Pid,N+1);
    {tcp_closed,Sock} ->
      ok;
    {Pid,shutdown} ->
      gen_tcp:close(Sock);
    {_PPid,comm,Msg} ->
      gen_tcp:send(Sock,Msg),
      do_loop(Sock,Pid,N)
  end.

%% Message manipulation & dispatch routine
manip_msg(_Pid,[0,0,Addr,MsgReq,MsgRes|Name]) ->
  %% Operation command dispatch -> Complex(devicemon + Message handler)
  cmdiface:reg_feedbackOps(Addr,Name,?DLYTIME,[MsgReq],[MsgRes],self());
manip_msg(_Pid,[0|Tail]) ->
  %% Seperation from the next part
  devicemon ! {self(),comm,[0|Tail]};
manip_msg(_Pid,[Addr,Cmd|Name]) when Addr<10 ->
  %% Seperation from the next part
  cmdiface:invoke_cmd(Addr,Name,[Cmd]);
manip_msg(Pid,Msg) -> % This needs improvements
  %% Fallback -> WTF
  Pid ! {self(),comm,Msg}.

createsock(Sock,Pid) ->
  Pid ! {self(),create,self()},
  ok = do_loop(Sock,Pid,0),
  Pid ! {self(),exiting}.

listenport(LSock,Pid) ->
  {ok,Sock} = gen_tcp:accept(LSock),
  gen_tcp:controlling_process(Sock,spawn(?MODULE,createsock,[Sock,Pid])),
  listenport(LSock,Pid).

portlistener(Port,Pid) ->
  {ok, LSock} = gen_tcp:listen(Port, ?TCP_OPTIONS),
  listenport(LSock,Pid).


monloop(Procs) ->
  receive
    {_Pid,shutdown} ->
      [ To ! shutdown || {_From,To} <- orddict:to_list(Procs) ];
    {Pid,create,To} ->
      monloop(orddict:store(Pid,To,Procs));
    {Pid,exiting} ->
      monloop(orddict:erase(Pid,Procs));
    {_Pid,comm,Msg} ->
      [ To ! {self(),comm,Msg} || {_From,To} <- orddict:to_list(Procs) ],
      monloop(Procs)
  end.

tcpmon(Port) ->
  Lis=spawn(?MODULE,portlistener,[Port,self()]),
  register(?MODULE,self()),
  monloop(orddict:new()),
  exit(Lis,shutdown).

start(Port) ->
  spawn(?MODULE,tcpmon,[Port]).

trap() -> trap().

test() ->
  start(5575),
  trap().