1 |
|
%% @doc Handles operations with #jingle_sip_session{} record |
2 |
|
-module(mod_jingle_sip_session). |
3 |
|
|
4 |
|
-export([set_incoming_request/5]). |
5 |
|
-export([set_incoming_handle/2]). |
6 |
|
-export([set_outgoing_request/4]). |
7 |
|
-export([set_outgoing_handle/4]). |
8 |
|
-export([set_outgoing_accepted/1]). |
9 |
|
-export([set_incoming_accepted/1]). |
10 |
|
-export([get_incoming_request/2]). |
11 |
|
-export([get_outgoing_handle/2]). |
12 |
|
-export([get_session_info/2]). |
13 |
|
-export([remove_session/1]). |
14 |
|
|
15 |
|
-include("mongoose.hrl"). |
16 |
|
-include("mod_jingle_sip_session.hrl"). |
17 |
|
|
18 |
|
-type call_id() :: binary(). |
19 |
|
-type incoming_request() :: {node(), binary()}. |
20 |
|
-type outgoing_handle() :: binary(). |
21 |
|
-type dialog_handle() :: nksip:handle(). |
22 |
|
-type request_id() :: binary(). |
23 |
|
-type session() :: #jingle_sip_session{ |
24 |
|
sid :: call_id(), |
25 |
|
dialog :: dialog_handle() | undefined, |
26 |
|
state :: accepted | ringing | undefined, |
27 |
|
direction :: in | out, |
28 |
|
request :: request_id() | undefined, |
29 |
|
node :: node(), |
30 |
|
owner :: jid:simple_bare_jid(), |
31 |
|
from :: jid:simple_bare_jid(), |
32 |
|
to :: jid:simple_bare_jid(), |
33 |
|
now :: integer(), |
34 |
|
meta :: #{init_stanza => exml:element()} |
35 |
|
}. |
36 |
|
-type update_fun() :: fun((session()) -> session() | {error, term()}). |
37 |
|
-export_type([call_id/0, session/0, update_fun/0]). |
38 |
|
|
39 |
|
-spec make_simple_bare_jid(jid:jid()) -> jid:simple_bare_jid(). |
40 |
|
make_simple_bare_jid(Jid) -> |
41 |
87 |
{_, _} = jid:to_lus(Jid). |
42 |
|
|
43 |
|
-spec set_incoming_request(CallID :: call_id(), ReqID :: request_id(), |
44 |
|
From :: jid:jid(), To :: jid:jid(), exml:element()) -> |
45 |
|
ok | {error, any()}. |
46 |
|
set_incoming_request(CallID, ReqID, From, To, JingleEl) -> |
47 |
15 |
Owner = make_simple_bare_jid(To), |
48 |
15 |
Meta = #{init_stanza => JingleEl}, |
49 |
15 |
Session = #jingle_sip_session{sid = CallID, |
50 |
|
request = ReqID, |
51 |
|
dialog = undefined, |
52 |
|
state = undefined, |
53 |
|
direction = in, |
54 |
|
node = node(), |
55 |
|
from = make_simple_bare_jid(From), |
56 |
|
to = Owner, |
57 |
|
owner = Owner, |
58 |
|
now = os:system_time(microsecond), |
59 |
|
meta = Meta}, |
60 |
15 |
mod_jingle_sip_backend:write_new_session(CallID, Session). |
61 |
|
|
62 |
|
-spec set_outgoing_request(CallID :: call_id(), ReqID :: request_id(), |
63 |
|
From :: jid:jid(), To :: jid:jid()) -> |
64 |
|
ok | {error, any()}. |
65 |
|
set_outgoing_request(CallID, ReqID, From, To) -> |
66 |
18 |
Owner = make_simple_bare_jid(From), |
67 |
18 |
Session = #jingle_sip_session{sid = CallID, |
68 |
|
request = ReqID, |
69 |
|
dialog = undefined, |
70 |
|
state = undefined, |
71 |
|
direction = out, |
72 |
|
node = node(), |
73 |
|
from = Owner, |
74 |
|
to = make_simple_bare_jid(To), |
75 |
|
owner = Owner, |
76 |
|
now = os:system_time(microsecond), |
77 |
|
meta = #{}}, |
78 |
18 |
mod_jingle_sip_backend:write_new_session(CallID, Session). |
79 |
|
|
80 |
|
-spec set_incoming_handle(CallID :: call_id(), DialogHandle :: dialog_handle()) -> |
81 |
|
ok | {error, any()}. |
82 |
|
set_incoming_handle(CallID, DialogHandle) -> |
83 |
15 |
F = fun(Session) -> do_set_incoming_handle(DialogHandle, Session) end, |
84 |
15 |
mod_jingle_sip_backend:update_session(CallID, F). |
85 |
|
|
86 |
|
do_set_incoming_handle(DialogHandle, Session = #jingle_sip_session{dialog = undefined, direction = in}) -> |
87 |
15 |
Session#jingle_sip_session{dialog = DialogHandle, |
88 |
|
node = node()}; |
89 |
|
do_set_incoming_handle(_, _) -> |
90 |
:-( |
{error, incoming_handle_exists}. |
91 |
|
|
92 |
|
-spec set_outgoing_handle(CallID :: call_id(), DialogHandle :: dialog_handle(), |
93 |
|
From :: jid:jid(), To :: jid:jid()) -> |
94 |
|
ok | {error, any()}. |
95 |
|
set_outgoing_handle(CallID, DialogHandle, From, To) -> |
96 |
17 |
F = fun(Session) -> do_set_outgoing_handle(DialogHandle, Session) end, |
97 |
17 |
case mod_jingle_sip_backend:update_session(CallID, F) of |
98 |
|
{error, not_found} -> |
99 |
:-( |
Owner = make_simple_bare_jid(From), |
100 |
:-( |
Session = #jingle_sip_session{sid = CallID, |
101 |
|
dialog = DialogHandle, |
102 |
|
node = node(), |
103 |
|
direction = out, |
104 |
|
state = ringing, |
105 |
|
from = Owner, |
106 |
|
to = make_simple_bare_jid(To), |
107 |
|
owner = Owner, |
108 |
|
now = os:system_time(microsecond), |
109 |
|
meta = #{}}, |
110 |
:-( |
mod_jingle_sip_backend:write_new_session(CallID, Session); |
111 |
|
Res -> |
112 |
17 |
Res |
113 |
|
end. |
114 |
|
|
115 |
|
do_set_outgoing_handle(DialogHandle, Session = #jingle_sip_session{dialog = undefined, direction = out}) -> |
116 |
17 |
Session#jingle_sip_session{dialog = DialogHandle, |
117 |
|
node = node()}; |
118 |
|
do_set_outgoing_handle(_, _) -> |
119 |
:-( |
{error, outgoing_handle_exists}. |
120 |
|
|
121 |
|
-spec set_incoming_accepted(CallID :: call_id()) -> |
122 |
|
ok | {error, any()}. |
123 |
|
set_incoming_accepted(CallID) -> |
124 |
9 |
mod_jingle_sip_backend:update_session(CallID, fun do_set_incoming_accepted/1). |
125 |
|
|
126 |
|
do_set_incoming_accepted(Session = #jingle_sip_session{direction = in, meta = Meta}) -> |
127 |
9 |
MetaWithoutInitStanza = maps:without([init_stanza], Meta), |
128 |
9 |
Session#jingle_sip_session{state = accepted, |
129 |
|
meta = MetaWithoutInitStanza}; |
130 |
|
do_set_incoming_accepted(_) -> |
131 |
:-( |
{error, not_found}. |
132 |
|
|
133 |
|
-spec set_outgoing_accepted(CallID :: call_id()) -> |
134 |
|
ok | {error, any()}. |
135 |
|
set_outgoing_accepted(CallID) -> |
136 |
11 |
mod_jingle_sip_backend:update_session(CallID, fun do_set_outgoing_accepted/1). |
137 |
|
|
138 |
|
do_set_outgoing_accepted(Session = #jingle_sip_session{direction = out}) -> |
139 |
11 |
Session#jingle_sip_session{state = accepted}; |
140 |
|
do_set_outgoing_accepted(_) -> |
141 |
:-( |
{error, not_found}. |
142 |
|
|
143 |
|
-spec get_incoming_request(call_id(), jid:jid()) -> {ok, undefined | incoming_request()} | |
144 |
|
{error, not_found}. |
145 |
|
get_incoming_request(CallID, User) -> |
146 |
10 |
UserUS = make_simple_bare_jid(User), |
147 |
10 |
case mod_jingle_sip_backend:read_session(CallID) of |
148 |
|
[#jingle_sip_session{request = ReqID, node = Node, owner = UserUS}] -> |
149 |
9 |
{ok, {Node, ReqID}}; |
150 |
|
_ -> |
151 |
1 |
{error, not_found} |
152 |
|
end. |
153 |
|
|
154 |
|
-spec get_outgoing_handle(call_id(), jid:jid()) -> {ok, undefined | outgoing_handle()} | |
155 |
|
{error, not_found}. |
156 |
|
get_outgoing_handle(SID, User) -> |
157 |
3 |
UserUS = make_simple_bare_jid(User), |
158 |
3 |
case mod_jingle_sip_backend:read_session(SID) of |
159 |
|
[#jingle_sip_session{dialog = Handle, owner = UserUS}] -> |
160 |
3 |
{ok, Handle}; |
161 |
|
_ -> |
162 |
:-( |
{error, not_found} |
163 |
|
end. |
164 |
|
|
165 |
|
-spec get_session_info(binary(), jid:jid()) -> |
166 |
|
{ok, map()} | {error, any()}. |
167 |
|
get_session_info(SID, User) -> |
168 |
8 |
UserUS = make_simple_bare_jid(User), |
169 |
8 |
case mod_jingle_sip_backend:read_session(SID) of |
170 |
|
[#jingle_sip_session{sid = SID, |
171 |
|
dialog = Handle, |
172 |
|
request = Request, |
173 |
|
state = State, |
174 |
|
direction = Dir, |
175 |
|
node = ONode, |
176 |
|
owner = UserUS, |
177 |
|
to = To, |
178 |
|
from = From, |
179 |
|
meta = Meta}] -> |
180 |
7 |
{ok, #{sid => SID, |
181 |
|
dialog => Handle, |
182 |
|
request => Request, |
183 |
|
state => State, |
184 |
|
direction => Dir, |
185 |
|
node => ONode, |
186 |
|
from => From, |
187 |
|
to => To, |
188 |
|
meta => Meta}}; |
189 |
|
_ -> |
190 |
1 |
{error, not_found} |
191 |
|
end. |
192 |
|
|
193 |
|
-spec remove_session(call_id()) -> ok. |
194 |
|
remove_session(CallID) -> |
195 |
18 |
mod_jingle_sip_backend:remove_session(CallID). |