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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
|
<?xml version="1.0" encoding="latin1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
</legalnotice>
<title>Running the stack</title>
<prepared>Håkan Mattsson</prepared>
<responsible>Håkan Mattsson</responsible>
<docno></docno>
<approved>Håkan Mattsson</approved>
<checked></checked>
<date>2007-06-15</date>
<rev>%VSN%</rev>
<file>megaco_run.xml</file>
</header>
<section>
<marker id="starting"></marker>
<title>Starting</title>
<p>A user may have a number of "virtual" connections to other
users. An MG is connected to at most one MGC, while an MGC may
be connected to any number of MG's. For each connection the user
selects a transport service, an encoding scheme and a user
callback module.</p>
<p>An MGC must initiate its transport service in order to listen
to MG's trying to connect. How the actual transport is initiated
is outside the scope of this application. However a send handle
(typically a socket id or host and port) must be provided from
the transport service in order to enable us to send the message
to the correct destination. We do however not assume anything
about this, from our point of view, opaque handle. Hopefully it
is rather small since it will passed around the system between
processes rather frequently.</p>
<p>A user may either be statically configured in a .config file
according to the application concept of Erlang/OTP or
dynamically started with the configuration settings as arguments
to megaco:start_user/2. These configuration settings may be
updated later on with megaco:update_conn_info/2.</p>
<p>The function megaco:connect/4 is used to tell the Megaco
application about which control process it should supervise,
which MID the remote user has, which callback module it should
use to send messages etc. When this "virtual" connection is
established the user may use megaco:call/3 and megaco:cast/3 in
order to send messages to the other side. Then it is up to the
MG to send its first Service Change Request message after
applying some clever algorithm in order to fight the problem
with startup avalanche (as discussed in the RFC).</p>
<p>The originating user will wait for a reply or a timeout
(defined by the request_timer). When it receives the reply this
will optionally be acknowledged (regulated by auto_ack), and
forwarded to the user. If an interim pending reply is received,
the long_request_timer will be used instead of the usual
request_timer, in order to enable avoidance of spurious re-sends
of the request.</p>
<p>On the destination side the transport service waits for
messages. Each message is forwarded to the Megaco application
via the megaco:receive_message/4 callback function. The
transport service may or may not provide means for blocking and
unblocking the reception of the incoming messages.</p>
<p></p>
<p>If a message is received before the "virtual" connection has
been established, the connection will be setup automatically. An
MGC may be real open minded and dynamically decide which
encoding and transport service to use depending on how the
transport layer contact is performed. For IP transports two
ports are standardized, one for textual encoding and one for
binary encoding. If for example an UDP packet was received on
the text port it would be possible to decide encoding and
transport on the fly.</p>
<p>After decoding a message various user callback functions are
invoked in order to allow the user to act properly. See the
megaco_user module for more info about the callback
arguments.</p>
<p>When the user has processed a transaction request in its
callback function, the Megaco application assembles a
transaction reply, encodes it using the selected encoding module
and sends the message back by invoking the callback
function:</p>
<list type="bulleted">
<item>
<p>SendMod:send_message(SendHandle, ErlangBinary)</p>
</item>
</list>
<p>Re-send of messages, handling pending transactions,
acknowledgements etc. is handled automatically by the Megaco
application but the user is free to override the default
behaviour by the various configuration possibilities. See
megaco:update_user_info/2 and megaco:update_conn_info/2 about
the possibilities.</p>
<p>When connections gets broken (that is explicitly by
megaco:disconnect/2 or when its controlling process dies) a user
callback function is invoked in order to allow the user to
re-establish the connection. The internal state of kept
messages, re-send timers etc. is not affected by this. A few
re-sends will of course fail while the connection is down, but
the automatic re-send algorithm does not bother about this and
eventually when the connection is up and running the messages
will be delivered if the timeouts are set to be long enough. The
user has the option of explicitly invoking megaco:cancel/2 to
cancel all messages for a connection.</p>
</section>
<section>
<marker id="mgc_startup_call_flow"></marker>
<title>MGC startup call flow</title>
<p>In order to prepare the MGC for the reception of the initial
message, hopefully a Service Change Request, the following needs
to be done:</p>
<list type="bulleted">
<item>
<p>Start the Megaco application.</p>
</item>
<item>
<p>Start the MGC user. This may either be done explicitly
with megaco:start_user/2 or implicitly by providing the -megaco
users configuration parameter.</p>
</item>
<item>
<p>Initiate the transport service and provide it with a
receive handle obtained from megaco:user_info/2.</p>
</item>
</list>
<p>When the initial message arrives the transport service
forwards it to the protocol engine which automatically
sets up the connection and invokes UserMod:handle_connect/2
before it invokes UserMod:handle_trans_request/3 with
the Service Change Request like this:</p>
<image file="MGC_startup_call_flow.gif">
<icaption>MGC Startup Call Flow</icaption>
</image>
</section>
<section>
<marker id="mg_startup_call_flow"></marker>
<title>MG startup call flow</title>
<p>In order to prepare the MG for the sending of the initial
message, hopefully a Service Change Request, the following needs
to be done:</p>
<list type="bulleted">
<item>
<p>Start the Megaco application.</p>
</item>
<item>
<p>Start the MG user. This may either be done explicitly
with megaco:start_user/2 or implicitly by providing the -megaco
users configuration parameter.</p>
</item>
<item>
<p>Initiate the transport service and provide it with a
receive handle obtained from megaco:user_info/2.</p>
</item>
<item>
<p>Setup a connection to the MGC with megaco:connect/4 and
provide it with a receive handle obtained from
megaco:user_info/2.</p>
</item>
</list>
<p>If the MG has been provisioned with the MID of the MGC it can
be given as the RemoteMid parameter to megaco:connect/4 and the
call flow will look like this:</p>
<image file="MG_startup_call_flow.gif">
<icaption>MG Startup Call Flow</icaption>
</image>
<p>If the MG cannot be provisioned with the MID of the MGC, the
MG can use the atom 'preliminary_mid' as the RemoteMid parameter
to megaco:connect/4 and the call flow will look like this:</p>
<image file="MG-startup_flow_noMID.gif">
<icaption>MG Startup Call Flow (no MID)</icaption>
</image>
</section>
<section>
<marker id="config_megaco"></marker>
<title>Configuring the Megaco stack</title>
<p>There are three kinds of configuration:</p>
<list type="bulleted">
<item>
<p>User info - Information related to megaco users. Read/Write. </p>
<p>A User is an entity identified by a MID, e.g. a MGC or a MG. </p>
<p>This information can be retrieved using
<seealso marker="megaco#user_info">megaco:user_info</seealso>. </p>
</item>
<item>
<p>Connection info - Information regarding connections. Read/Write.</p>
<p>This information can be retrieved using
<seealso marker="megaco#conn_info">megaco:conn_info</seealso>. </p>
</item>
<item>
<p>System info - System wide information. Read only.</p>
<p>This information can be retrieved using
<seealso marker="megaco#system_info">megaco:system_info</seealso>. </p>
</item>
</list>
</section>
<section>
<marker id="initial_config"></marker>
<title>Initial configuration</title>
<p>The initial configuration of the Megaco should be defined in the
Erlang system configuration file. The following configured parameters
are defined for the Megaco application:</p>
<list type="bulleted">
<item>
<p><c><![CDATA[users = [{Mid, [user_config()]}].]]></c></p>
<p>Each user is represented by a tuple with the Mid of the user and a
list of config parameters (each parameter is in turn a tuple:
<c><![CDATA[{Item, Value}]]></c>).</p>
</item>
<item>
<p><c><![CDATA[scanner = flex | {Module, Function, Arguments, Modules}]]></c></p>
<!--
For future use
<p><c><![CDATA[scanner = flex | {flex, Opts} | {Module, Function, Arguments, Modules}]]></c></p>
-->
<list type="bulleted">
<item>
<p><c><![CDATA[flex]]></c> will result in the start of the flex scanner with default
options.</p>
</item>
<!--
For future use
<item>
<p><c><![CDATA[{flex, Opts}]]></c> will result in the start of the flex scanner with the
specified options. <c>Opts</c> is two-tuple list where the only allowed option is
<c>{smp, boolean()}</c>, with default value being <c>false</c> and the value of
<c>true</c> resulting in a start of an smp-optimized scanner. </p>
</item>
-->
<item>
<p>The MFA alternative makes it possible for Megaco to start and
supervise a scanner written by the user (see
<c><![CDATA[supervisor:start_child]]></c> for an explanation of the
parameters).</p>
</item>
</list>
</item>
</list>
<p>See also <seealso marker="megaco_encode#text_config">Configuration of text encoding module(s)</seealso>
for more info. </p>
</section>
<section>
<marker id="changing_config"></marker>
<title>Changing the configuration</title>
<p>The configuration can be changed during runtime. This is done with
the functions <seealso marker="megaco#update_user_info">megaco:update_user_info</seealso> and
<seealso marker="megaco#update_conn_info">megaco:update_conn_info</seealso></p>
</section>
<section>
<marker id="transaction_sender"></marker>
<title>The transaction sender</title>
<p>The transaction sender is a process (one per connection), which handle
all transaction sending, if so configured (see
<seealso marker="megaco#user_info">megaco:user_info</seealso> and
<seealso marker="megaco#conn_info">megaco:conn_info</seealso>).</p>
<p>The purpose of the transaction sender is to accumulate transactions
for a more efficient message sending. The transactions that are
accumulated are transaction request and transaction ack. For
transaction ack's the benefit is quite large, since the transactions
are small and it is possible to have ranges (which means that
transaction acks for transactions 1, 2, 3 and 4 can be sent as a
range 1-4 in one transaction ack, instead of four separate
transactions). </p>
<p>There are a number of configuration parameter's that control the
operation of the transaction sender. In principle, a message with
everything stored (ack's and request's) is sent from the process
when:</p>
<list type="bulleted">
<item>
<p>When <c><![CDATA[trans_timer]]></c> expires.</p>
</item>
<item>
<p>When <c><![CDATA[trans_ack_maxcount]]></c> number of ack's has been
received.</p>
</item>
<item>
<p>When <c><![CDATA[trans_req_maxcount]]></c> number of requests's has
been received.</p>
</item>
<item>
<p>When the size of all received requests exceeds
<c><![CDATA[trans_req_maxsize]]></c>.</p>
</item>
<item>
<p>When a reply transaction is sent.</p>
</item>
<item>
<p>When a pending transaction is sent.</p>
</item>
</list>
<p>When something is to be sent, everything is packed into one message,
unless the trigger was a reply transaction and the added size of the
reply and all the requests is greater then
<c><![CDATA[trans_req_maxsize]]></c>, in which case the stored
transactions are sent first in a separate message and the reply in
another message.</p>
<p>When the transaction sender receives a request which is already
"in storage" (indicated by the transaction id) it is assumed to
be a resend and everything stored is sent. This could happen if
the values of the <c><![CDATA[trans_timer]]></c> and the
<c><![CDATA[request_timer]]></c> is not properly chosen.</p>
</section>
<section>
<marker id="segment_reply"></marker>
<title>Segmentation of transaction replies</title>
<p>In version 3 of the megaco standard the Segmentation package was
introduced. Simply, this package defines a procedure to segment
megaco messages (transaction replies) when using a transport that
does not automatically do this (e.g. UDP). See also
<seealso marker="megaco_encode#handling_versions">version3</seealso>.</p>
<p>Although it would be both pointless and counterproductive to use
segmentation on a transport that already does this (e.g. TCP), the
megaco application does not check this. Instead, it is up to the
user to configure this properly. </p>
<list type="bulleted">
<item>
<p>Receiving segmented messages: </p>
<p>This is handled automatically by the megaco application.
There is however one thing that need to be configured by the user,
the
<seealso marker="megaco#user_info">segment_recv_timer</seealso>
option. </p>
<p>Note that the segments are delivered to the user differently
depending on which function is used to issue the original request.
When issuing the request using the
<seealso marker="megaco#cast">megaco:cast</seealso> function,
the segments are delivered to the user via the
<seealso marker="megaco_user#trans_reply">handle_trans_reply</seealso>
callback function one at a time, as they arrive. But this obviously
doe not work for the
<seealso marker="megaco#call">megaco:call</seealso> function.
In this case, the segments are accumulated and then delivered
all at once as the function returns.</p>
</item>
<item>
<p>Sending segmented messages: </p>
<p>This is also handled automatically by the megaco application.
First of all, segmentation is only attempted if so configured, see
the <seealso marker="megaco#user_info">segment_send</seealso> option.
Secondly, megaco relies on the ability of the used codec to
encode action replies, which is the smallest component the
megaco application handles when segmenting. Thirdly, the
reply will be segmented only if the sum of the size of the
action replies (plus an arbitrary message header size) are greater
then the specified max message size (see the
<seealso marker="megaco#user_info">max_pdu_size</seealso> option).
Finally, if segmentation is decided, then each action reply
will make up its own (segment) message.</p>
</item>
</list>
</section>
</chapter>
|