1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2001-2019. 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%% Purpose: Test application config
24%%----------------------------------------------------------------------
25
26-module(megaco_sdp_SUITE).
27
28-export([
29	 suite/0, all/0, groups/0,
30	 init_per_suite/1,    end_per_suite/1,
31         init_per_group/2,    end_per_group/2,
32	 init_per_testcase/2, end_per_testcase/2,
33
34	 decode_encode/1,
35	 otp8123/1
36	]).
37
38-include_lib("megaco/include/megaco.hrl").
39-include_lib("megaco/include/megaco_message_v1.hrl").
40-include_lib("megaco/include/megaco_sdp.hrl").
41-include("megaco_test_lib.hrl").
42
43
44
45%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46%% Top test case
47%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48
49
50suite() ->
51    [{ct_hooks, [ts_install_cth]}].
52
53all() ->
54    [
55     decode_encode,
56     {group, tickets}
57    ].
58
59groups() ->
60    [
61     {tickets, [], tickets_cases()}
62    ].
63
64tickets_cases() ->
65    [
66     otp8123
67    ].
68
69
70%%
71%% -----
72%%
73
74init_per_suite(suite) ->
75    [];
76init_per_suite(doc) ->
77    [];
78init_per_suite(Config0) when is_list(Config0) ->
79
80    ?ANNOUNCE_SUITE_INIT(),
81
82    p("init_per_suite -> entry with"
83      "~n      Config: ~p"
84      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
85
86    case ?LIB:init_per_suite([{sysmon, false}|Config0]) of
87        {skip, _} = SKIP ->
88            SKIP;
89
90        Config1 when is_list(Config1) ->
91
92            p("init_per_suite -> end when"
93              "~n      Config: ~p"
94              "~n      Nodes:  ~p", [Config1, erlang:nodes()]),
95
96            Config1
97    end.
98
99end_per_suite(suite) -> [];
100end_per_suite(doc) -> [];
101end_per_suite(Config0) when is_list(Config0) ->
102
103    p("end_per_suite -> entry with"
104      "~n      Config: ~p"
105      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
106
107    Config1 = ?LIB:end_per_suite(Config0),
108
109    p("end_per_suite -> end when"
110      "~n      Nodes:  ~p", [erlang:nodes()]),
111
112    Config1.
113
114
115
116%%
117%% -----
118%%
119
120init_per_group(_GroupName, Config) ->
121    p("init_per_group -> entry with"
122      "~n   Config: ~p"
123      "~n", [Config]),
124    Config.
125
126end_per_group(_GroupName, Config) ->
127    p("end_per_group -> entry with"
128      "~n   Config: ~p"
129      "~n", [Config]),
130    Config.
131
132
133
134
135%%
136%% -----
137%%
138
139init_per_testcase(Case, Config) ->
140
141    p("init_per_testcase -> entry with"
142      "~n   Config: ~p"
143      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
144
145    megaco_test_lib:init_per_testcase(Case, Config).
146
147end_per_testcase(Case, Config) ->
148
149    p("end_per_testcase -> entry with"
150      "~n   Config: ~p"
151      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
152
153    megaco_test_lib:end_per_testcase(Case, Config).
154
155
156
157
158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159
160decode_encode(suite) ->
161    [];
162decode_encode(Config) when is_list(Config) ->
163    io:format("decode_encode -> entry with"
164	      "~n   Config: ~p"
165	      "~n", [Config]),
166
167    %%-------------------------------------
168    %% Test data
169    %%-------------------------------------
170
171    %% -- (PP) (ok) --
172    io:format("setup for protocol version 01 (ok)~n", []),
173    PP_V01_V    = 0,
174    PP_V01      = cre_PropertyParm_v(PP_V01_V),
175    SDP_V01     = cre_sdp_v(PP_V01_V),
176    PP_V01_Exp  = {ok, SDP_V01},
177    SDP_V01_Exp = {ok, PP_V01},
178
179
180    %% -- (PP) (ok) --
181    io:format("setup for protocol version 02 (ok)~n", []),
182    PP_V02_V    = 100,
183    PP_V02      = cre_PropertyParm_v(PP_V02_V),
184    SDP_V02     = cre_sdp_v(PP_V02_V),
185    PP_V02_Exp  = {ok, SDP_V02},
186    SDP_V02_Exp = {ok, PP_V02},
187
188
189    %% -- (PP) (error) --
190    io:format("setup for protocol version 03 (error)~n", []),
191    PP_V03_V    = "sune",
192    PP_V03      = cre_PropertyParm_v(PP_V03_V),
193    SDP_V03     = cre_sdp_v(PP_V03_V),
194    PP_V03_Exp  = {error, {invalid_protocol_version, PP_V03_V}},
195    SDP_V03_Exp = PP_V03_Exp,
196
197
198    %% -- (PP) (ok) --
199    io:format("setup for connection info 01 (ok)~n", []),
200    PP_C01_CA    = "123.123.123.120",
201    PP_C01       = cre_PropertyParm_c(ip4, PP_C01_CA),
202    SDP_C01      = cre_sdp_c(ip4, PP_C01_CA),
203    PP_C01_Exp   = {ok, SDP_C01},
204    SDP_C01_Exp  = {ok, PP_C01},
205
206
207    %% -- (PP) (ok) --
208    io:format("setup for connection info 02 (ok)~n", []),
209    PP_C02_TTL   = 121,
210    PP_C02_Base  = "123.123.123.121",
211    PP_C02       = cre_PropertyParm_c(ip4, PP_C02_Base, PP_C02_TTL),
212    SDP_C02_CA   = #megaco_sdp_c_conn_addr{base = PP_C02_Base,
213					   ttl  = PP_C02_TTL},
214    SDP_C02      = cre_sdp_c(ip4, SDP_C02_CA),
215    PP_C02_Exp   = {ok, SDP_C02},
216    SDP_C02_Exp  = {ok, PP_C02},
217
218
219    %% -- (PP) (ok) --
220    io:format("setup for connection info 03 (ok)~n", []),
221    PP_C03_CA    = "123.123.123.122",
222    PP_C03       = cre_PropertyParm_c(ip4, PP_C03_CA ++ "/"),
223    SDP_C03      = cre_sdp_c(ip4, PP_C03_CA),
224    PP_C03_Exp   = {ok, SDP_C03},
225    SDP_C03_Exp  = {ok, cre_PropertyParm_c(ip4, PP_C03_CA)},
226
227
228    %% -- (PP) (error) --
229    io:format("setup for connection info 04 (error)~n", []),
230    PP_C04_Base = "123.123.123.123",
231    PP_C04_TTL  = "sune",
232    PP_C04_CA   = PP_C04_Base ++ "/" ++ PP_C04_TTL,
233    PP_C04      = cre_PropertyParm_c(ip4, PP_C04_CA),
234    PP_C04_Exp  = {error, {invalid_connection_data_conn_addr_ttl, "sune"}},
235
236
237    %% -- (PP) (ok) --
238    io:format("setup for connection info 05 (ok)~n", []),
239    PP_C05_TTL   = 124,
240    PP_C05_NOF   = 224,
241    PP_C05_Base  = "123.123.123.124",
242    PP_C05       = cre_PropertyParm_c(ip4, PP_C05_Base, PP_C05_TTL,
243				      PP_C05_NOF),
244    SDP_C05_CA   = #megaco_sdp_c_conn_addr{base   = PP_C05_Base,
245					   ttl    = PP_C05_TTL,
246					   num_of = PP_C05_NOF},
247    SDP_C05      = cre_sdp_c(ip4, SDP_C05_CA),
248    PP_C05_Exp   = {ok, SDP_C05},
249    SDP_C05_Exp  = {ok, PP_C05},
250
251
252    %% -- (PP) (ok) --
253    io:format("setup for connection info 06 (ok)~n", []),
254    PP_C06_TTL   = 125,
255    PP_C06_Base  = "123.123.123.125",
256    PP_C06_CA    = PP_C06_Base ++ "/" ++ integer_to_list(PP_C06_TTL) ++ "/",
257    PP_C06       = cre_PropertyParm_c(ip4, PP_C06_CA),
258    SDP_C06_CA   = #megaco_sdp_c_conn_addr{base = PP_C06_Base,
259					   ttl  = PP_C06_TTL},
260    SDP_C06      = cre_sdp_c(ip4, SDP_C06_CA),
261    PP_C06_Exp   = {ok, SDP_C06},
262    SDP_C06_Exp  = {ok, cre_PropertyParm_c(ip4, PP_C06_Base ++ "/" ++ integer_to_list(PP_C06_TTL))},
263
264
265    %% -- (PP) (error) --
266    io:format("setup for connection info 07 (ok)~n", []),
267    PP_C07_NOF  = "sune",
268    PP_C07_TTL  = 125,
269    PP_C07_Base = "123.123.123.126",
270    PP_C07_CA   = PP_C07_Base ++ "/" ++
271	integer_to_list(PP_C07_TTL) ++ "/" ++ PP_C07_NOF,
272    PP_C07      = cre_PropertyParm_c(ip4, PP_C07_CA),
273    SDP_C07_CA  = #megaco_sdp_c_conn_addr{base   = PP_C07_Base,
274					  ttl    = PP_C07_TTL,
275					  num_of = PP_C07_NOF},
276    SDP_C07     = cre_sdp_c(ip4, SDP_C07_CA),
277    PP_C07_Exp  = {error, {invalid_connection_data_conn_addr_num_of, PP_C07_NOF}},
278    SDP_C07_Exp = {error, {invalid_connection_data_conn_addr_num_of, PP_C07_NOF}},
279
280
281    %% -- (PP) (ok) --
282    io:format("setup for connection info 08 (ok)~n", []),
283    PP_C08_CA   = "FF1E:03AD::7F2E:172A:1E24",
284    PP_C08      = cre_PropertyParm_c(ip6, PP_C08_CA),
285    SDP_C08     = cre_sdp_c(ip6, PP_C08_CA),
286    PP_C08_Exp  = {ok, SDP_C08},
287    SDP_C08_Exp = {ok, PP_C08},
288
289
290    %% -- (PP) (ok) --
291    io:format("setup for media announcement 01 (ok)~n", []),
292    PP_M01_Media     = audio,
293    PP_M01_Port      = 2000,
294    PP_M01_Transport = "RTP/AVP",
295    PP_M01_FMT_LST   = ["0"],
296    PP_M01           = cre_PropertyParm_m(PP_M01_Media,
297					  PP_M01_Port,
298					  PP_M01_Transport,
299					  PP_M01_FMT_LST),
300    SDP_M01     = cre_sdp_m(PP_M01_Media, PP_M01_Port,
301			    PP_M01_Transport, PP_M01_FMT_LST),
302    PP_M01_Exp  = {ok, SDP_M01},
303    SDP_M01_Exp = {ok, PP_M01},
304
305
306    %% -- (PP) (ok) --
307    io:format("setup for media announcement 02 (ok)~n", []),
308    PP_M02_Media     = audio,
309    PP_M02_Port      = 2000,
310    PP_M02_NOP       = 2,
311    PP_M02_Transport = "RTP/AVP",
312    PP_M02_FMT_LST   = ["0"],
313    PP_M02           = cre_PropertyParm_m(PP_M02_Media, PP_M02_Port,
314					  PP_M02_NOP, PP_M02_Transport,
315					  PP_M02_FMT_LST),
316    SDP_M02          = cre_sdp_m(PP_M02_Media, PP_M02_Port, PP_M02_NOP,
317				 PP_M02_Transport, PP_M02_FMT_LST),
318    PP_M02_Exp       = {ok, SDP_M02},
319    SDP_M02_Exp      = {ok, PP_M02},
320
321    %% -- (PP) (ok) --
322    io:format("setup for origin 01 (ok)~n", []),
323    PP_O01_Name = "kalle",
324    PP_O01_SID  = 1414,
325    PP_O01_V    = 2,
326    PP_O01_AT   = ip4,
327    PP_O01_A    = "126.12.64.4",
328    PP_O01      = cre_PropertyParm_o(PP_O01_Name, PP_O01_SID, PP_O01_V,
329				     PP_O01_AT, PP_O01_A),
330    SDP_O01     = cre_sdp_o(PP_O01_Name, PP_O01_SID, PP_O01_V,
331			    PP_O01_AT, PP_O01_A),
332    PP_O01_Exp  = {ok, SDP_O01},
333    SDP_O01_Exp = {ok, PP_O01},
334
335
336    %% -- (PP) (ok) --
337    io:format("setup for origin 02 (ok)~n", []),
338    PP_O02_Name = "bobbe",
339    PP_O02_SID  = 1515,
340    PP_O02_V    = 3,
341    PP_O02_NT   = in,
342    PP_O02_AT   = ip6,
343    PP_O02_A    = "2201:056D::112E:144A:1E24",
344    PP_O02      = cre_PropertyParm_o(PP_O02_Name, PP_O02_SID, PP_O02_V,
345				    PP_O02_NT, PP_O02_AT, PP_O02_A),
346    SDP_O02     = cre_sdp_o(PP_O02_Name, PP_O02_SID, PP_O02_V, PP_O02_NT,
347			    PP_O02_AT, PP_O02_A),
348    PP_O02_Exp  = {ok, SDP_O02},
349    SDP_O02_Exp = {ok, PP_O02},
350
351
352    %% -- (PP) (ok) --
353    PP_A01_PL   = 2,
354    PP_A01_EN   = "G726-32",
355    PP_A01_CR   = 8000,
356    PP_A01      = cre_PropertyParm_rtpmap(PP_A01_PL, PP_A01_EN, PP_A01_CR),
357    SDP_A01     = cre_sdp_a_rtpmap(PP_A01_PL, PP_A01_EN, PP_A01_CR),
358    PP_A01_Exp  = {ok, SDP_A01},
359    SDP_A01_Exp = {ok, PP_A01},
360
361
362    %% -- (PP) (ok) --
363    PP_A02_PL   = 2,
364    PP_A02_EN   = "xxx",
365    PP_A02_CR   = 42,
366    PP_A02_EP   = ["1","2","3"],
367    PP_A02      = cre_PropertyParm_rtpmap(PP_A02_PL, PP_A02_EN,
368					  PP_A02_CR, PP_A02_EP),
369    SDP_A02     = cre_sdp_a_rtpmap(PP_A02_PL, PP_A02_EN, PP_A02_CR, PP_A02_EP),
370    PP_A02_Exp  = {ok, SDP_A02},
371    SDP_A02_Exp = {ok, PP_A02},
372
373
374    %% -- (PP) (ok) --
375    PP_A03_PT   = 12,
376    PP_A03      = cre_PropertyParm_ptime(PP_A03_PT),
377    SDP_A03     = cre_sdp_a_ptime(PP_A03_PT),
378    PP_A03_Exp  = {ok, SDP_A03},
379    SDP_A03_Exp = {ok, PP_A03},
380
381
382    %% -- (PP) (error) --
383    PP_A04_PT   = "sune",
384    PP_A04      = cre_PropertyParm_ptime(PP_A04_PT),
385    SDP_A04     = cre_sdp_a_ptime(PP_A04_PT),
386    PP_A04_Exp  = {error, {invalid_ptime_packet_time, PP_A04_PT}},
387    SDP_A04_Exp = {error, {invalid_ptime_packet_time, PP_A04_PT}},
388
389
390    %% -- (PP) (ok) --
391    PP_A05_QA   = 10,
392    PP_A05      = cre_PropertyParm_quality(PP_A05_QA),
393    SDP_A05     = cre_sdp_a_quality(PP_A05_QA),
394    PP_A05_Exp  = {ok, SDP_A05},
395    SDP_A05_Exp = {ok, PP_A05},
396
397
398    %% -- (PP) (error) --
399    PP_A06_QA   = "sune",
400    PP_A06      = cre_PropertyParm_quality(PP_A06_QA),
401    SDP_A06     = cre_sdp_a_quality(PP_A06_QA),
402    PP_A06_Exp  = {error, {invalid_quality_quality, PP_A06_QA}},
403    SDP_A06_Exp = {error, {invalid_quality_quality, PP_A06_QA}},
404
405
406    %% -- (PP) (ok) --
407    PP_A07_A    = "recvonly",
408    PP_A07      = cre_PropertyParm_a(PP_A07_A),
409    SDP_A07     = cre_sdp_a(PP_A07_A),
410    PP_A07_Exp  = {ok, SDP_A07},
411    SDP_A07_Exp = {ok, PP_A07},
412
413
414    %% -- (PP) (ok) --
415    PP_A08_V    = portrait,
416    PP_A08      = cre_PropertyParm_orient(PP_A08_V),
417    SDP_A08     = cre_sdp_a_orient(PP_A08_V),
418    PP_A08_Exp  = {ok, SDP_A08},
419    SDP_A08_Exp = {ok, PP_A08},
420
421
422    %% -- (PP) (ok) --
423    PP_A09_V    = landscape,
424    PP_A09      = cre_PropertyParm_orient(PP_A09_V),
425    SDP_A09     = cre_sdp_a_orient(PP_A09_V),
426    PP_A09_Exp  = {ok, SDP_A09},
427    SDP_A09_Exp = {ok, PP_A09},
428
429
430    %% -- (PP) (ok) --
431    PP_A10_V    = seascape,
432    PP_A10      = cre_PropertyParm_orient(PP_A10_V),
433    SDP_A10     = cre_sdp_a_orient(PP_A10_V),
434    PP_A10_Exp  = {ok, SDP_A10},
435    SDP_A10_Exp = {ok, PP_A10},
436
437
438    %% -- (PP) (error) --
439    PP_A11_V    = gurka,
440    SDP_A11_V   = atom_to_list(PP_A11_V),
441    PP_A11      = cre_PropertyParm_orient(PP_A11_V),
442    SDP_A11     = cre_sdp_a_orient(PP_A11_V),
443    PP_A11_Exp  = {error, {invalid_orient_orientation, SDP_A11_V}},
444    SDP_A11_Exp = {error, {invalid_orient_orientation, PP_A11_V}},
445
446
447    %% -- (PP) (ok) --
448    PP_A12_V    = "gurka",
449    PP_A12      = cre_PropertyParm_cat(PP_A12_V),
450    SDP_A12     = cre_sdp_a_cat(PP_A12_V),
451    PP_A12_Exp  = {ok, SDP_A12},
452    SDP_A12_Exp = {ok, PP_A12},
453
454
455    %% -- (PP) (ok) --
456    PP_A13_V    = "gurka",
457    PP_A13      = cre_PropertyParm_keywds(PP_A13_V),
458    SDP_A13     = cre_sdp_a_keywds(PP_A13_V),
459    PP_A13_Exp  = {ok, SDP_A13},
460    SDP_A13_Exp = {ok, PP_A13},
461
462
463    %% -- (PP) (ok) --
464    PP_A14_V    = "gurka 1.0",
465    PP_A14      = cre_PropertyParm_tool(PP_A14_V),
466    SDP_A14     = cre_sdp_a_tool(PP_A14_V),
467    PP_A14_Exp  = {ok, SDP_A14},
468    SDP_A14_Exp = {ok, PP_A14},
469
470
471    %% -- (PP) (ok) --
472    PP_A15_V    = 15,
473    PP_A15      = cre_PropertyParm_maxptime(PP_A15_V),
474    SDP_A15     = cre_sdp_a_maxptime(PP_A15_V),
475    PP_A15_Exp  = {ok, SDP_A15},
476    SDP_A15_Exp = {ok, PP_A15},
477
478
479    %% -- (PP) (error) --
480    PP_A16_V    = "gurka",
481    PP_A16      = cre_PropertyParm_maxptime(PP_A16_V),
482    SDP_A16     = cre_sdp_a_maxptime(PP_A16_V),
483    PP_A16_Exp  = {error, {invalid_maxptime_maximum_packet_time, PP_A16_V}},
484    SDP_A16_Exp = {error, {invalid_maxptime_maximum_packet_time, PP_A16_V}},
485
486
487    %% -- (PP) (ok) --
488    PP_A17_V    = "H332",
489    PP_A17      = cre_PropertyParm_type(PP_A17_V ),
490    SDP_A17     = cre_sdp_a_type(PP_A17_V),
491    PP_A17_Exp  = {ok, SDP_A17},
492    SDP_A17_Exp = {ok, PP_A17},
493
494
495    %% -- (PP) (ok) --
496    PP_A18_V    = "ISO-8859-1",
497    PP_A18      = cre_PropertyParm_charset(PP_A18_V),
498    SDP_A18     = cre_sdp_a_charset(PP_A18_V),
499    PP_A18_Exp  = {ok, SDP_A18},
500    SDP_A18_Exp = {ok, PP_A18},
501
502
503    %% -- (PP) (ok) --
504    PP_A19_PT   = "gurka",
505    PP_A19      = cre_PropertyParm_sdplang(PP_A19_PT),
506    SDP_A19     = cre_sdp_a_sdplang(PP_A19_PT),
507    PP_A19_Exp  = {ok, SDP_A19},
508    SDP_A19_Exp = {ok, PP_A19},
509
510
511    %% -- (PP) (ok) --
512    PP_A20_PT   = "gurka",
513    PP_A20      = cre_PropertyParm_lang(PP_A20_PT),
514    SDP_A20     = cre_sdp_a_lang(PP_A20_PT),
515    PP_A20_Exp  = {ok, SDP_A20},
516    SDP_A20_Exp = {ok, PP_A20},
517
518
519    %% -- (PP) (ok) --
520    PP_A21_PT   = "21.0",
521    PP_A21      = cre_PropertyParm_framerate(PP_A21_PT),
522    SDP_A21     = cre_sdp_a_framerate(PP_A21_PT),
523    PP_A21_Exp  = {ok, SDP_A21},
524    SDP_A21_Exp = {ok, PP_A21},
525
526
527%%     %% -- (PP) (ok) --
528%%     PP_A22_PT   = "ISO-8859-1",
529%%     PP_A22      = cre_PropertyParm_(PP_A22_T),
530%%     SDP_A22     = cre_sdp_a_(PP_A22_PT),
531%%     PP_A22_Exp  = {ok, SDP_A22},
532%%     SDP_A22_Exp = {ok, PP_A22},
533
534
535    %% -- (PP) (ok) --
536    PP_A23_FORMAT = "125",
537    PP_A23_PARAM  = "profile-level-id=222; max-br=1212; max-mbps=20200",
538    PP_A23        = cre_PropertyParm_a_fmtp(PP_A23_FORMAT, PP_A23_PARAM),
539    SDP_A23       = cre_sdp_a_fmtp(PP_A23_FORMAT, PP_A23_PARAM),
540    PP_A23_Exp    = {ok, SDP_A23},
541    SDP_A23_Exp   = {ok, PP_A23},
542
543
544    %% -- (PP) (ok) --
545    PP_B01_MOD  = "2",
546    PP_B01_BW   = 523,
547    PP_B01      = cre_PropertyParm_b(PP_B01_MOD, PP_B01_BW),
548    SDP_B01     = cre_sdp_b(PP_B01_MOD, PP_B01_BW),
549    PP_B01_Exp  = {ok, SDP_B01},
550    SDP_B01_Exp = {ok, PP_B01},
551
552
553    %% -- (PP) (error) --
554    PP_B02_B   = "sune",
555    PP_B02     = cre_PropertyParm("b", PP_B02_B),
556    PP_B02_Exp = {error, {invalid_PropertyParm,
557			  {bandwidth_info, PP_B02_B, [PP_B02_B]}}},
558
559
560    %% -- (PP) (ok) --
561    PP_B03_MOD  = "X",
562    PP_B03_BW   = 525,
563    PP_B03      = cre_PropertyParm_b(PP_B03_MOD, PP_B03_BW),
564    SDP_B03     = cre_sdp_b(PP_B03_MOD, PP_B03_BW),
565    PP_B03_Exp  = {ok, SDP_B03},
566    SDP_B03_Exp = {ok, PP_B03},
567
568
569    %% -- (PP) (error) --
570    PP_B04_BWT  = "X",
571    PP_B04_BW   = "sune",
572    PP_B04      = cre_PropertyParm_b(PP_B04_BWT, PP_B04_BW),
573    SDP_B04     = cre_sdp_b(PP_B04_BWT, PP_B04_BW),
574    PP_B04_Exp  = {error, {invalid_bandwidth_bandwidth, PP_B04_BW}},
575    SDP_B04_Exp = {error, {invalid_bandwidth_bandwidth, PP_B04_BW}},
576
577
578    %% -- (PP) (ok) --
579    PP_T01_START = 1200,
580    PP_T01_STOP  = 1300,
581    PP_T01       = cre_PropertyParm_t(PP_T01_START, PP_T01_STOP),
582    SDP_T01      = cre_sdp_t(PP_T01_START, PP_T01_STOP),
583    PP_T01_Exp   = {ok, SDP_T01},
584    SDP_T01_Exp  = {ok, PP_T01},
585
586
587    %% -- (PP) (ok) --
588    PP_R01_RPT  = "10",
589    PP_R01_DUR  = "100",
590    PP_R01_LOO  = ["2", "4", "6"],
591    PP_R01      = cre_PropertyParm_r(PP_R01_RPT, PP_R01_DUR, PP_R01_LOO),
592    SDP_R01     = cre_sdp_r(PP_R01_RPT, PP_R01_DUR, PP_R01_LOO),
593    PP_R01_Exp  = {ok, SDP_R01},
594    SDP_R01_Exp = {ok, PP_R01},
595
596
597    %% -- (PP) (ok) --
598    PP_Z01_LOA_V1 = #megaco_sdp_z_adjustement{time   = "12121212",
599					      offset = "-1h"},
600    PP_Z01_LOA_V2 = #megaco_sdp_z_adjustement{time   = "34343434",
601					      offset = "0"},
602    PP_Z01_LOA  = [PP_Z01_LOA_V1, PP_Z01_LOA_V2],
603    PP_Z01      = cre_PropertyParm_z(PP_Z01_LOA),
604    SDP_Z01     = cre_sdp_z(PP_Z01_LOA),
605    PP_Z01_Exp  = {ok, SDP_Z01},
606    SDP_Z01_Exp = {ok, PP_Z01},
607
608
609    %% -- (PP) (error) --
610    PP_Z02      = cre_PropertyParm("z", []),
611    SDP_Z02     = cre_sdp_z([]),
612    PP_Z02_Exp  = {error, {invalid_tzones_list_of_adjustments, []}},
613    SDP_Z02_Exp = {error, {invalid_tzones_list_of_adjustments, []}},
614
615
616    %% -- (PP) (ok) --
617    PP_K01_M    = prompt,
618    PP_K01_EK   = undefined,
619    PP_K01      = cre_PropertyParm_k(PP_K01_M, PP_K01_EK),
620    SDP_K01     = cre_sdp_k(PP_K01_M),
621    PP_K01_Exp  = {ok, SDP_K01},
622    SDP_K01_Exp = {ok, PP_K01},
623
624
625    %% -- (PP) (ok) --
626    PP_K02_M    = clear,
627    PP_K02_EK   = "whatever",
628    PP_K02      = cre_PropertyParm_k(PP_K02_M, PP_K02_EK),
629    SDP_K02     = cre_sdp_k(PP_K02_M, PP_K02_EK),
630    PP_K02_Exp  = {ok, SDP_K02},
631    SDP_K02_Exp = {ok, PP_K02},
632
633
634    %% -- (PP) (ok) --
635    PP_K03_M    = "method",
636    PP_K03_EK   = "key",
637    PP_K03      = cre_PropertyParm_k(PP_K03_M, PP_K03_EK),
638    SDP_K03     = cre_sdp_k(PP_K03_M, PP_K03_EK),
639    PP_K03_Exp  = {ok, SDP_K03},
640    SDP_K03_Exp = {ok, PP_K03},
641
642
643    %% -- (PP) (ok) --
644    PP_S01_SN   = "new session",
645    PP_S01      = cre_PropertyParm_s(PP_S01_SN),
646    SDP_S01     = cre_sdp_s(PP_S01_SN),
647    PP_S01_Exp  = {ok, SDP_S01},
648    SDP_S01_Exp = {ok, PP_S01},
649
650
651    %% -- (PP) (ok) --
652    PP_I01_SD   = "Session and Media Information",
653    PP_I01      = cre_PropertyParm_i(PP_I01_SD),
654    SDP_I01     = cre_sdp_i(PP_I01_SD),
655    PP_I01_Exp  = {ok, SDP_I01},
656    SDP_I01_Exp = {ok, PP_I01},
657
658
659    %% -- (PP) (ok) --
660    PP_U01_URI  = "http://www.erlang.org/",
661    PP_U01      = cre_PropertyParm_u(PP_U01_URI),
662    SDP_U01     = cre_sdp_u(PP_U01_URI),
663    PP_U01_Exp  = {ok, SDP_U01},
664    SDP_U01_Exp = {ok, PP_U01},
665
666
667    %% -- (PP) (ok) --
668    PP_E01_EMAIL = "kalle@company.se",
669    PP_E01       = cre_PropertyParm_e(PP_E01_EMAIL),
670    SDP_E01      = cre_sdp_e(PP_E01_EMAIL),
671    PP_E01_Exp   = {ok, SDP_E01},
672    SDP_E01_Exp  = {ok, PP_E01},
673
674
675    %% -- (PP) (ok) --
676    PP_P01_PHONE = "+1 713 555 1234",
677    PP_P01       = cre_PropertyParm_p(PP_P01_PHONE),
678    SDP_P01      = cre_sdp_p(PP_P01_PHONE),
679    PP_P01_Exp   = {ok, SDP_P01},
680    SDP_P01_Exp  = {ok, PP_P01},
681
682
683    %% -- (PP) (error) --
684    PP_N01     = cre_PropertyParm("not_recognized", "whatever"),
685    PP_N01_Exp = {error, undefined_PropertyParm},
686
687
688    %% -- (PG) (ok) --
689    PG01    = [{PP_V01, ok},
690	       {PP_C01, ok},
691	       {PP_M01, ok}],
692
693
694    %% -- (PG) (ok) --
695    PG02    = [{PP_V02, ok},
696	       {PP_C05, ok},
697	       {PP_A02, ok}],
698
699
700    %% -- (PG) (error) --
701    PG03    = [{PP_V03, error},
702	       {PP_C08, ok},
703	       {PP_M02, ok}],
704
705
706    %% -- (PG) (error) --
707    PG04   = [{PP_V02, ok},
708	      {PP_C04, error},
709	      {PP_C07, error}],
710
711
712    %% -- (PGs) (ok) --
713    PGS01 = [PG01, PG02],
714
715
716    %% -- (PGs) (error) --
717    PGS02 = [PG01, PG04],
718
719
720    Instructions =
721	[
722	 pp_dec_instruction("version 01 - dec [ok]", PP_V01,  PP_V01_Exp),
723	 pp_enc_instruction("version 01 - enc [ok]", SDP_V01, SDP_V01_Exp),
724	 pp_dec_instruction("version 02 - dec [ok]", PP_V02,  PP_V02_Exp),
725	 pp_enc_instruction("version 02 - enc [ok]", SDP_V02, SDP_V02_Exp),
726	 pp_dec_instruction("version 03 - dec [error]", PP_V03,  PP_V03_Exp),
727	 pp_enc_instruction("version 03 - enc [error]", SDP_V03, SDP_V03_Exp),
728	 pp_dec_instruction("connection info 01 - dec [ok]", PP_C01,  PP_C01_Exp),
729	 pp_enc_instruction("connection info 01 - enc [ok]", SDP_C01, SDP_C01_Exp),
730	 pp_dec_instruction("connection info 02 - dec [ok]", PP_C02,  PP_C02_Exp),
731	 pp_enc_instruction("connection info 02 - enc [ok]", SDP_C02, SDP_C02_Exp),
732	 pp_dec_instruction("connection info 03 - dec [ok]", PP_C03,  PP_C03_Exp),
733	 pp_enc_instruction("connection info 03 - enc [ok]", SDP_C03, SDP_C03_Exp),
734	 pp_dec_instruction("connection info 04 - dec [error]", PP_C04,  PP_C04_Exp),
735
736	 pp_dec_instruction("connection info 05 - dec [ok]", PP_C05,  PP_C05_Exp),
737	 pp_enc_instruction("connection info 05 - enc [ok]", SDP_C05, SDP_C05_Exp),
738	 pp_dec_instruction("connection info 06 - dec [ok]", PP_C06,  PP_C06_Exp),
739	 pp_enc_instruction("connection info 06 - enc [ok]", SDP_C06, SDP_C06_Exp),
740	 pp_dec_instruction("connection info 07 - dec [error]", PP_C07,  PP_C07_Exp),
741	 pp_enc_instruction("connection info 07 - enc [error]", SDP_C07, SDP_C07_Exp),
742	 pp_dec_instruction("connection info 08 - dec [ok]", PP_C08,  PP_C08_Exp),
743	 pp_enc_instruction("connection info 08 - enc [ok]", SDP_C08, SDP_C08_Exp),
744	 pp_dec_instruction("media announcement 01 - dec [ok]", PP_M01,  PP_M01_Exp),
745	 pp_enc_instruction("media announcement 01 - enc [ok]", SDP_M01, SDP_M01_Exp),
746	 pp_dec_instruction("media announcement 02 - dec [ok]", PP_M02,  PP_M02_Exp),
747	 pp_enc_instruction("media announcement 02 - enc [ok]", SDP_M02, SDP_M02_Exp),
748	 pp_dec_instruction("origin 01 - dec [ok]", PP_O01,  PP_O01_Exp),
749	 pp_enc_instruction("origin 01 - enc [ok]", SDP_O01, SDP_O01_Exp),
750	 pp_dec_instruction("origin 02 - dec [ok]", PP_O02,  PP_O02_Exp),
751	 pp_enc_instruction("origin 02 - enc [ok]", SDP_O02, SDP_O02_Exp),
752	 pp_dec_instruction("attributes 01 - dec [ok]", PP_A01,  PP_A01_Exp),
753	 pp_enc_instruction("attributes 01 - enc [ok]", SDP_A01, SDP_A01_Exp),
754	 pp_dec_instruction("attributes 02 - dec [ok]", PP_A02,  PP_A02_Exp),
755	 pp_enc_instruction("attributes 02 - enc [ok]", SDP_A02, SDP_A02_Exp),
756	 pp_dec_instruction("attributes 03 - dec [ok]", PP_A03,  PP_A03_Exp),
757	 pp_enc_instruction("attributes 03 - enc [ok]", SDP_A03, SDP_A03_Exp),
758	 pp_dec_instruction("attributes 04 - dec [error]", PP_A04,  PP_A04_Exp),
759	 pp_enc_instruction("attributes 04 - enc [error]", SDP_A04, SDP_A04_Exp),
760	 pp_dec_instruction("attributes 05 - dec [ok]", PP_A05,  PP_A05_Exp),
761	 pp_enc_instruction("attributes 05 - enc [ok]", SDP_A05, SDP_A05_Exp),
762	 pp_dec_instruction("attributes 06 - dec [error]", PP_A06,  PP_A06_Exp),
763	 pp_enc_instruction("attributes 06 - dec [error]", SDP_A06, SDP_A06_Exp),
764	 pp_dec_instruction("attributes 07 - dec [ok]", PP_A07,  PP_A07_Exp),
765	 pp_enc_instruction("attributes 07 - enc [ok]", SDP_A07, SDP_A07_Exp),
766	 pp_dec_instruction("attributes 08 - dec [ok]", PP_A08,  PP_A08_Exp),
767	 pp_enc_instruction("attributes 08 - enc [ok]", SDP_A08, SDP_A08_Exp),
768
769	 pp_dec_instruction("attributes 09 - dec [ok]", PP_A09,  PP_A09_Exp),
770	 pp_enc_instruction("attributes 09 - enc [ok]", SDP_A09, SDP_A09_Exp),
771	 pp_dec_instruction("attributes 10 - dec [ok]", PP_A10,  PP_A10_Exp),
772	 pp_enc_instruction("attributes 10 - enc [ok]", SDP_A10, SDP_A10_Exp),
773	 pp_dec_instruction("attributes 11 - dec [error]", PP_A11,  PP_A11_Exp),
774	 pp_enc_instruction("attributes 11 - enc [error]", SDP_A11, SDP_A11_Exp),
775
776	 pp_dec_instruction("attributes 12 - dec [ok]", PP_A12,  PP_A12_Exp),
777	 pp_enc_instruction("attributes 12 - enc [ok]", SDP_A12, SDP_A12_Exp),
778	 pp_dec_instruction("attributes 13 - dec [ok]", PP_A13,  PP_A13_Exp),
779	 pp_enc_instruction("attributes 13 - enc [ok]", SDP_A13, SDP_A13_Exp),
780	 pp_dec_instruction("attributes 14 - dec [ok]", PP_A14,  PP_A14_Exp),
781	 pp_enc_instruction("attributes 14 - enc [ok]", SDP_A14, SDP_A14_Exp),
782	 pp_dec_instruction("attributes 15 - dec [ok]", PP_A15,  PP_A15_Exp),
783	 pp_enc_instruction("attributes 15 - enc [ok]", SDP_A15, SDP_A15_Exp),
784	 pp_dec_instruction("attributes 16 - dec [error]", PP_A16,  PP_A16_Exp),
785	 pp_enc_instruction("attributes 16 - enc [error]", SDP_A16, SDP_A16_Exp),
786	 pp_dec_instruction("attributes 17 - dec [ok]", PP_A17,  PP_A17_Exp),
787	 pp_enc_instruction("attributes 17 - enc [ok]", SDP_A17, SDP_A17_Exp),
788	 pp_dec_instruction("attributes 18 - dec [ok]", PP_A18,  PP_A18_Exp),
789	 pp_enc_instruction("attributes 18 - enc [ok]", SDP_A18, SDP_A18_Exp),
790	 pp_dec_instruction("attributes 19 - dec [ok]", PP_A19,  PP_A19_Exp),
791	 pp_enc_instruction("attributes 19 - enc [ok]", SDP_A19, SDP_A19_Exp),
792	 pp_dec_instruction("attributes 20 - dec [ok]", PP_A20,  PP_A20_Exp),
793	 pp_enc_instruction("attributes 20 - enc [ok]", SDP_A20, SDP_A20_Exp),
794	 pp_dec_instruction("attributes 21 - dec [ok]", PP_A21,  PP_A21_Exp),
795	 pp_enc_instruction("attributes 21 - enc [ok]", SDP_A21, SDP_A21_Exp),
796	 pp_dec_instruction("attributes 23 - dec [ok]", PP_A23,  PP_A23_Exp),
797	 pp_enc_instruction("attributes 24 - enc [ok]", SDP_A23, SDP_A23_Exp),
798
799	 pp_dec_instruction("bandwidth 01 - dec [ok]", PP_B01,  PP_B01_Exp),
800	 pp_enc_instruction("bandwidth 01 - enc [ok]", SDP_B01, SDP_B01_Exp),
801	 pp_dec_instruction("bandwidth 02 - dec [ok]", PP_B02,  PP_B02_Exp),
802
803	 pp_dec_instruction("bandwidth 03 - dec [ok]", PP_B03,  PP_B03_Exp),
804	 pp_enc_instruction("bandwidth 03 - enc [ok]", SDP_B03, SDP_B03_Exp),
805	 pp_dec_instruction("bandwidth 04 - dec [error]", PP_B04,  PP_B04_Exp),
806	 pp_enc_instruction("bandwidth 04 - enc [error]", SDP_B04, SDP_B04_Exp),
807	 pp_dec_instruction("times 01 - dec [ok]", PP_T01,  PP_T01_Exp),
808	 pp_enc_instruction("times 01 - enc [ok]", SDP_T01, SDP_T01_Exp),
809	 pp_dec_instruction("repeat times 01 - dec [ok]", PP_R01,  PP_R01_Exp),
810	 pp_enc_instruction("repeat times 01 - enc [ok]", SDP_R01, SDP_R01_Exp),
811	 pp_dec_instruction("time zones 01 - dec [ok]", PP_Z01,  PP_Z01_Exp),
812	 pp_enc_instruction("time zones 01 - enc [ok]", SDP_Z01, SDP_Z01_Exp),
813	 pp_dec_instruction("time zones 02 - dec [error]", PP_Z02,  PP_Z02_Exp),
814	 pp_enc_instruction("time zones 02 - enc [error]", SDP_Z02, SDP_Z02_Exp),
815	 pp_dec_instruction("encryption keys 01 - dec [ok]", PP_K01,  PP_K01_Exp),
816	 pp_enc_instruction("encryption keys 01 - enc [ok]", SDP_K01, SDP_K01_Exp),
817	 pp_dec_instruction("encryption keys 01 - dec [ok]", PP_K02,  PP_K02_Exp),
818	 pp_enc_instruction("encryption keys 01 - enc [ok]", SDP_K02, SDP_K02_Exp),
819	 pp_dec_instruction("encryption keys 01 - dec [ok]", PP_K03,  PP_K03_Exp),
820	 pp_enc_instruction("encryption keys 01 - enc [ok]", SDP_K03, SDP_K03_Exp),
821	 pp_dec_instruction("session name 01 - dec [ok]", PP_S01,  PP_S01_Exp),
822	 pp_enc_instruction("session name 01 - enc [ok]", SDP_S01, SDP_S01_Exp),
823	 pp_dec_instruction("session and media information 01 - dec [ok]", PP_I01,  PP_I01_Exp),
824	 pp_enc_instruction("session and media information 01 - enc [ok]", SDP_I01, SDP_I01_Exp),
825	 pp_dec_instruction("uri 01 - dec [ok]", PP_U01,  PP_U01_Exp),
826	 pp_enc_instruction("uri 01 - enc [ok]", SDP_U01, SDP_U01_Exp),
827	 pp_dec_instruction("email 01 - dec [ok]", PP_E01,  PP_E01_Exp),
828	 pp_enc_instruction("email 01 - enc [ok]", SDP_E01, SDP_E01_Exp),
829	 pp_dec_instruction("phone 01 - dec [ok]", PP_P01,  PP_P01_Exp),
830	 pp_enc_instruction("phone 01 - enc [ok]", SDP_P01, SDP_P01_Exp),
831	 pp_dec_instruction("undefined 01 - dec [error]", PP_N01,  PP_N01_Exp),
832
833	 pg_dec_instruction("property group 01 - ok", PG01),
834	 pg_dec_instruction("property group 02 - ok", PG02),
835	 pg_dec_instruction("property group 03 - error", PG03),
836	 pg_dec_instruction("property group 04 - error", PG04),
837
838	 pgs_dec_instruction("property groups 01 - ok", PGS01),
839	 pgs_dec_instruction("property groups 02 - error", PGS02)
840
841	],
842    exec(Instructions).
843
844
845verify_decode_pg([], []) ->
846    ok;
847verify_decode_pg([{PP, error}|PPs], [{PP, _Err}|SDPs]) ->
848    verify_decode_pg(PPs, SDPs);
849verify_decode_pg([{PP, ok}|_], [{PP, _Err}|_]) ->
850    error;
851verify_decode_pg([{_PP, _ExpStatus}|PG], [_SDP|SDP_PG]) ->
852    verify_decode_pg(PG, SDP_PG).
853
854verify_decode_pgs(PGS, SDP_PGS) ->
855    verify_decode_pg(lists:flatten(PGS), lists:flatten(SDP_PGS)).
856
857
858%% ===============================================================
859
860otp8123(suite) ->
861    [];
862otp8123(Config) when is_list(Config) ->
863    io:format("otp8123 -> entry with"
864	      "~n   Config: ~p"
865	      "~n", [Config]),
866
867    Instructions =
868	[
869	 pg_dec_instruction("property group 01 - dec [ok]", otp8123_pg1()),
870	 pg_dec_instruction("property group 02 - dec [ok]", otp8123_pg2()),
871	 pg_dec_instruction("property group 03 - dec [ok]", otp8123_pg3()),
872	 pg_dec_instruction("property group 04 - dec [ok]", otp8123_pg4())
873	],
874    exec(Instructions),
875    ok.
876
877otp8123_pg1() ->
878    PP1 = #'PropertyParm'{name = "m",
879			  value = ["audio 49154 RTP/AVP 8"]},
880    PP2 = #'PropertyParm'{name = "a",
881			  value = ["maxptime: 30"]},
882    PP3 = #'PropertyParm'{name = "a",
883			  value = ["ptime:2"]},
884    PP4 = #'PropertyParm'{name = "a",
885			  value = ["tpmap:8 PCMA/8000/1"]},
886    PG = [PP1, PP2, PP3, PP4],
887    [{PP, ok} || PP <- PG].
888
889otp8123_pg2() ->
890    PP1 = #'PropertyParm'{name = "m",
891			  value = ["audio 49154 RTP/AVP 8"]},
892    PP2 = #'PropertyParm'{name = "a",
893			  value = ["maxptime: 30 "]},
894    PP3 = #'PropertyParm'{name = "a",
895			  value = ["ptime:2"]},
896    PP4 = #'PropertyParm'{name = "a",
897			  value = ["tpmap:8 PCMA/8000/1"]},
898    PG = [PP1, PP2, PP3, PP4],
899    [{PP, ok} || PP <- PG].
900
901otp8123_pg3() ->
902    PP1 = #'PropertyParm'{name = "m",
903			  value = ["audio 49154 RTP/AVP 8"]},
904    PP2 = #'PropertyParm'{name = "a",
905			  value = ["maxptime:30"]},
906    PP3 = #'PropertyParm'{name = "a",
907			  value = ["ptime: 2"]},
908    PP4 = #'PropertyParm'{name = "a",
909			  value = ["tpmap:8 PCMA/8000/1"]},
910    PG = [PP1, PP2, PP3, PP4],
911    [{PP, ok} || PP <- PG].
912
913otp8123_pg4() ->
914    PP1 = #'PropertyParm'{name = "m",
915			  value = ["audio 49154 RTP/AVP 8"]},
916    PP2 = #'PropertyParm'{name = "a",
917			  value = ["maxptime:30"]},
918    PP3 = #'PropertyParm'{name = "a",
919			  value = ["ptime: 2 "]},
920    PP4 = #'PropertyParm'{name = "a",
921			  value = ["tpmap:8 PCMA/8000/1"]},
922    PG = [PP1, PP2, PP3, PP4],
923    [{PP, ok} || PP <- PG].
924
925
926
927%% ===============================================================
928%%
929%% Instruction engine
930%%
931
932instr_verify_pp(Expected) ->
933    fun(Res) ->
934	    case Res of
935		Expected -> ok;
936		_        -> {error, Expected}
937	    end
938    end.
939
940instr_verify_dec_pg(Data) ->
941    fun({ok, SDP}) ->
942	    verify_decode_pg(Data, SDP);
943       (_Bad)      ->
944	    error
945    end.
946
947instr_verify_dec_pgs(Data) ->
948    fun({ok, SDP}) ->
949	    verify_decode_pgs(Data, SDP);
950       (_Bad)      ->
951	    error
952    end.
953
954
955pp_dec_instruction(Desc, Data, Exp) ->
956    dec_instruction(Desc, Data, instr_verify_pp(Exp)).
957
958pp_enc_instruction(Desc, Data, Exp) ->
959    enc_instruction(Desc, Data, instr_verify_pp(Exp)).
960
961pg_dec_instruction(Desc, Data0) ->
962    Data = [D || {D, _} <- Data0],
963    dec_instruction(Desc, Data, instr_verify_dec_pg(Data0)).
964
965pgs_dec_instruction(Desc, Data0) ->
966    Data = [[D || {D, _} <- PG] || PG <- Data0],
967    dec_instruction(Desc, Data, instr_verify_dec_pgs(Data0)).
968
969dec_instruction(Desc, Data, Verify) ->
970    instruction(Desc, fun(D) -> megaco:decode_sdp(D) end, Data, Verify).
971
972enc_instruction(Desc, Data, Verify) ->
973    instruction(Desc, fun(D) -> megaco:encode_sdp(D) end, Data, Verify).
974
975instruction(Desc, Cmd, Data, Verify) ->
976    {Desc, Cmd, Data, Verify}.
977
978exec(Instructions) ->
979    exec(Instructions, []).
980
981exec([], []) ->
982    ok;
983exec([], Acc) ->
984    {error, lists:reverse(Acc)};
985exec([Instr|Instructions], Acc) ->
986    case exec_instruction(Instr) of
987	ok ->
988	    exec(Instructions, Acc);
989	Error ->
990	    exec(Instructions, [Error|Acc])
991    end.
992
993
994exec_instruction({Desc, Cmd, Data, Verify}) ->
995    io:format("~n"
996	      "*** Test ~s ***"
997	      "~n", [Desc]),
998    Res = (catch Cmd(Data)),
999    case (catch Verify(Res)) of
1000	ok ->
1001	    ok;
1002	error ->
1003	    {error, {instruction_failed, {Desc, Data, Res}}};
1004	{error, Expected} ->
1005	    {error, {instruction_failed, {Desc, Data, Res, Expected}}};
1006	Else ->
1007	    {error, {verification_error, {Desc, Data, Res, Else}}}
1008    end.
1009
1010
1011%% ===============================================================
1012%%
1013%% Utility functions to generate PropertyParm records
1014%%
1015
1016cre_PropertyParm_p(Num) when is_list(Num) ->
1017    cre_PropertyParm("p", Num).
1018
1019cre_sdp_p(PN) ->
1020    #megaco_sdp_p{phone_number = PN}.
1021
1022cre_PropertyParm_e(Email) when is_list(Email) ->
1023    cre_PropertyParm("e", Email).
1024
1025cre_sdp_e(E) ->
1026    #megaco_sdp_e{email = E}.
1027
1028cre_PropertyParm_u(URI) when is_list(URI) ->
1029    cre_PropertyParm("u", URI).
1030
1031cre_sdp_u(U) ->
1032    #megaco_sdp_u{uri = U}.
1033
1034cre_PropertyParm_i(SessionDescr) when is_list(SessionDescr) ->
1035    cre_PropertyParm("i", SessionDescr).
1036
1037cre_sdp_i(SD) ->
1038    #megaco_sdp_i{session_descriptor = SD}.
1039
1040cre_PropertyParm_s(Name) when is_list(Name) ->
1041    cre_PropertyParm("s", Name).
1042
1043cre_sdp_s(N) ->
1044    #megaco_sdp_s{name = N}.
1045
1046cre_PropertyParm_k(prompt, _) ->
1047    cre_PropertyParm("k", "prompt");
1048cre_PropertyParm_k(clear, EncryptionKey) when is_list(EncryptionKey) ->
1049    cre_PropertyParm("k", "clear:" ++ EncryptionKey);
1050cre_PropertyParm_k(base64, EncryptionKey) when is_list(EncryptionKey) ->
1051    cre_PropertyParm("k", "base64:" ++ EncryptionKey);
1052cre_PropertyParm_k(uri, EncryptionKey) when is_list(EncryptionKey) ->
1053    cre_PropertyParm("k", "uri:" ++ EncryptionKey);
1054cre_PropertyParm_k(Method, EncryptionKey)
1055  when is_list(Method) and is_list(EncryptionKey) ->
1056    cre_PropertyParm("k", Method ++ ":" ++ EncryptionKey).
1057
1058cre_sdp_k(M) ->
1059    #megaco_sdp_k{method = M}.
1060cre_sdp_k(M, EK) ->
1061    #megaco_sdp_k{method = M, encryption_key = EK}.
1062
1063cre_PropertyParm_z([H | _] = LOA) when is_record(H, megaco_sdp_z_adjustement) ->
1064    F = fun(#megaco_sdp_z_adjustement{time = T, offset = O}, Str) ->
1065		Str ++ " " ++ T ++ " " ++ O
1066	end,
1067    cre_PropertyParm("z", lists:foldl(F, [], LOA)).
1068
1069cre_sdp_z(LOA) ->
1070    #megaco_sdp_z{list_of_adjustments = LOA}.
1071
1072cre_PropertyParm_r(Repeat, Duration, ListOfOffsets)
1073  when is_list(Repeat) and is_list(Duration) and is_list(ListOfOffsets) ->
1074    F = fun(Elem, Str) -> Str ++ " " ++ Elem end,
1075    Val = Repeat ++ " " ++ Duration ++  lists:foldl(F, [], ListOfOffsets),
1076    cre_PropertyParm("r", Val).
1077
1078cre_sdp_r(Repeat, Duration, ListOfOffsets) ->
1079    #megaco_sdp_r{repeat_interval = Repeat,
1080		  active_duration = Duration,
1081		  list_of_offsets = ListOfOffsets}.
1082
1083cre_PropertyParm_t(Start, Stop)
1084  when is_list(Start) and is_list(Stop) ->
1085    cre_PropertyParm("t", Start ++ " " ++ Stop);
1086cre_PropertyParm_t(Start, Stop) ->
1087    cre_PropertyParm_t(i2s(Start), i2s(Stop)).
1088
1089cre_sdp_t(Start, Stop) ->
1090    #megaco_sdp_t{start = Start, stop = Stop}.
1091
1092cre_PropertyParm_b(BwType, Bandwidth)
1093  when is_list(BwType) and is_integer(Bandwidth) ->
1094    cre_PropertyParm_b(BwType, i2s(Bandwidth));
1095cre_PropertyParm_b(BwType, Bandwidth)
1096  when is_list(BwType) and is_list(Bandwidth) ->
1097    cre_PropertyParm("b", BwType ++ ":" ++ Bandwidth).
1098
1099cre_sdp_b(BWT, BW) ->
1100    #megaco_sdp_b{bwtype = BWT, bandwidth = BW}.
1101
1102
1103cre_PropertyParm_cat(Cat) when is_list(Cat) ->
1104    cre_PropertyParm_a("cat", Cat).
1105
1106cre_sdp_a_cat(C) ->
1107    #megaco_sdp_a_cat{category = C}.
1108
1109
1110cre_PropertyParm_keywds(KeyWds) when is_list(KeyWds) ->
1111    cre_PropertyParm_a("keywds", KeyWds).
1112
1113cre_sdp_a_keywds(KW) ->
1114    #megaco_sdp_a_keywds{keywords = KW}.
1115
1116
1117cre_PropertyParm_tool(NameAndVersion) when is_list(NameAndVersion) ->
1118    cre_PropertyParm_a("tool", NameAndVersion).
1119
1120cre_sdp_a_tool(NAV) ->
1121    #megaco_sdp_a_tool{name_and_version = NAV}.
1122
1123
1124cre_PropertyParm_ptime(PacketTime) when is_integer(PacketTime) ->
1125    cre_PropertyParm_ptime(i2s(PacketTime));
1126cre_PropertyParm_ptime(PacketTime) when is_list(PacketTime) ->
1127    cre_PropertyParm_a("ptime", PacketTime).
1128
1129cre_sdp_a_ptime(PT) ->
1130    #megaco_sdp_a_ptime{packet_time = PT}.
1131
1132
1133cre_PropertyParm_maxptime(MaxPacketTime) when is_integer(MaxPacketTime) ->
1134    cre_PropertyParm_maxptime(i2s(MaxPacketTime));
1135cre_PropertyParm_maxptime(MaxPacketTime) when is_list(MaxPacketTime) ->
1136    cre_PropertyParm_a("maxptime", MaxPacketTime).
1137
1138cre_sdp_a_maxptime(PT) ->
1139    #megaco_sdp_a_maxptime{maximum_packet_time = PT}.
1140
1141
1142cre_PropertyParm_rtpmap(Payload, EncName, ClockRate) ->
1143    cre_PropertyParm_rtpmap(Payload, EncName, ClockRate, []).
1144
1145cre_PropertyParm_rtpmap(Payload, EncName, ClockRate, EncPar)
1146  when is_integer(Payload) and
1147       is_list(EncName) and
1148       is_integer(ClockRate) and
1149       is_list(EncPar) ->
1150    F = fun(Elem, Str) -> Str ++ "/" ++ Elem end,
1151    Val =
1152	integer_to_list(Payload) ++ " " ++
1153	EncName ++ "/" ++ integer_to_list(ClockRate) ++
1154	lists:foldl(F, [], EncPar),
1155    cre_PropertyParm_a("rtpmap", Val).
1156
1157cre_sdp_a_rtpmap(Payload, EncName, ClockRate) ->
1158    #megaco_sdp_a_rtpmap{payload_type  = Payload,
1159			 encoding_name = EncName,
1160			 clock_rate    = ClockRate}.
1161cre_sdp_a_rtpmap(Payload, EncName, ClockRate, EncParms) ->
1162    #megaco_sdp_a_rtpmap{payload_type   = Payload,
1163			 encoding_name  = EncName,
1164			 clock_rate     = ClockRate,
1165			 encoding_parms = EncParms}.
1166
1167cre_PropertyParm_orient(Orientation) when is_atom(Orientation) ->
1168    cre_PropertyParm_orient(atom_to_list(Orientation));
1169cre_PropertyParm_orient(Orientation) when is_list(Orientation) ->
1170    cre_PropertyParm_a("orient", Orientation).
1171
1172cre_sdp_a_orient(O) ->
1173    #megaco_sdp_a_orient{orientation = O}.
1174
1175cre_PropertyParm_type(CT) when is_list(CT) ->
1176    cre_PropertyParm_a("type", CT).
1177
1178cre_sdp_a_type(CT) ->
1179    #megaco_sdp_a_type{conf_type = CT}.
1180
1181cre_PropertyParm_charset(CS) when is_list(CS) ->
1182    cre_PropertyParm_a("charset", CS).
1183
1184cre_sdp_a_charset(CS) ->
1185    #megaco_sdp_a_charset{char_set = CS}.
1186
1187cre_PropertyParm_sdplang(L) when is_list(L) ->
1188    cre_PropertyParm_a("sdplang", L).
1189
1190cre_sdp_a_sdplang(L) ->
1191    #megaco_sdp_a_sdplang{tag = L}.
1192
1193cre_PropertyParm_lang(L) when is_list(L) ->
1194    cre_PropertyParm_a("lang", L).
1195
1196cre_sdp_a_lang(L) ->
1197    #megaco_sdp_a_lang{tag = L}.
1198
1199cre_PropertyParm_framerate(FR) when is_list(FR) ->
1200    cre_PropertyParm_a("framerate", FR).
1201
1202cre_sdp_a_framerate(FR) ->
1203    #megaco_sdp_a_framerate{frame_rate = FR}.
1204
1205cre_PropertyParm_quality(Quality) when is_integer(Quality) ->
1206    cre_PropertyParm_quality(i2s(Quality));
1207cre_PropertyParm_quality(Quality) when is_list(Quality) ->
1208    cre_PropertyParm_a("quality", Quality).
1209
1210cre_sdp_a_quality(Qa) ->
1211    #megaco_sdp_a_quality{quality = Qa}.
1212
1213cre_PropertyParm_a(Attr, AttrValue)
1214  when is_list(Attr) and is_list(AttrValue) ->
1215    cre_PropertyParm("a", Attr ++ ":" ++ AttrValue).
1216
1217cre_PropertyParm_a(Attr) when is_list(Attr) ->
1218    cre_PropertyParm("a", Attr).
1219
1220cre_PropertyParm_a_fmtp(Format, Param)
1221  when is_list(Format) and is_list(Param) ->
1222    cre_PropertyParm_a("fmtp", Format ++ " " ++ Param).
1223
1224cre_sdp_a_fmtp(Fmt, Parm) ->
1225    #megaco_sdp_a_fmtp{format = Fmt, param = Parm}.
1226
1227cre_sdp_a(Attr) ->
1228    #megaco_sdp_a{attribute = Attr}.
1229
1230%% cre_sdp_a(Attr, Val) ->
1231%%     #megaco_sdp_a{attribute = Attr,
1232%% 		  value     = Val}.
1233
1234cre_PropertyParm_o(User, SID, Version, AddrType, Addr) ->
1235    cre_PropertyParm_o(User, SID, Version, in, AddrType, Addr).
1236
1237cre_PropertyParm_o(User, SID, Version, NetType, AddrType, Addr)
1238  when is_list(User) and
1239       is_integer(SID) and
1240       is_integer(Version) and
1241       is_list(NetType) or (NetType == in) and
1242       is_list(AddrType) or ((AddrType == ip4) or (AddrType == ip6)) and
1243       is_list(Addr) ->
1244    NT = case NetType of
1245	     in -> "IN";
1246	     _  -> NetType
1247	 end,
1248    AT = case AddrType of
1249	     ip4 -> "IP4";
1250	     ip6 -> "IP6";
1251	     _   -> AddrType
1252	 end,
1253    Val =
1254	User         ++ " " ++
1255	i2s(SID)     ++ " " ++
1256	i2s(Version) ++ " " ++
1257	NT           ++ " " ++
1258	AT           ++ " " ++
1259	Addr,
1260    cre_PropertyParm("o", Val).
1261
1262cre_sdp_o(Name, SID, V, AddrType, Addr) ->
1263    cre_sdp_o(Name, SID, V, in, AddrType, Addr).
1264cre_sdp_o(Name, SID, V, NetType, AddrType, Addr) ->
1265    #megaco_sdp_o{user_name    = Name,
1266		  session_id   = SID,
1267		  version      = V,
1268		  network_type = NetType,
1269		  address_type = AddrType,
1270		  address      = Addr}.
1271
1272cre_PropertyParm_m(Media, Port, Transport, FmtList)
1273  when is_atom(Media) ->
1274    cre_PropertyParm_m(atom_to_list(Media),
1275		       Port, Transport, FmtList);
1276cre_PropertyParm_m(Media, Port0, Transport, FmtList)
1277  when is_list(Media) and is_list(Transport) and is_list(FmtList) ->
1278    Port = i2s(Port0),
1279    Val =
1280	Media ++ " " ++ Port ++ " " ++ Transport ++ " " ++ val(FmtList),
1281    cre_PropertyParm("m", Val).
1282
1283cre_PropertyParm_m(Media, Port, NumPorts, Transport, FmtList)
1284  when is_atom(Media) ->
1285    cre_PropertyParm_m(atom_to_list(Media),
1286		       Port, NumPorts, Transport, FmtList);
1287cre_PropertyParm_m(Media, Port0, NumPorts0, Transport, FmtList)
1288  when is_list(Media) and is_list(Transport) and is_list(FmtList) ->
1289    Port     = i2s(Port0),
1290    NumPorts = i2s(NumPorts0),
1291    Val =
1292	Media ++ " " ++ Port ++ "/" ++ NumPorts ++ " " ++ Transport ++
1293	" " ++ val(FmtList),
1294    cre_PropertyParm("m", Val).
1295
1296cre_sdp_m(Media, Port, Transport, FmtList) ->
1297    #megaco_sdp_m{media     = Media,
1298		  port      = Port,
1299		  transport = Transport,
1300		  fmt_list  = FmtList}.
1301
1302cre_sdp_m(Media, Port, NumPorts, Transport, FmtList) ->
1303    #megaco_sdp_m{media     = Media,
1304		  port      = Port,
1305		  num_ports = NumPorts,
1306		  transport = Transport,
1307		  fmt_list  = FmtList}.
1308
1309
1310cre_PropertyParm_c(ip4, ConnAddr) ->
1311    cre_PropertyParm_c("IP4", ConnAddr);
1312cre_PropertyParm_c(ip6, ConnAddr) ->
1313    cre_PropertyParm_c("IP6", ConnAddr);
1314cre_PropertyParm_c(AddrType, ConnAddr)
1315  when is_list(AddrType) and is_list(ConnAddr) ->
1316    Val = "IN " ++ AddrType ++ " " ++ ConnAddr,
1317    cre_PropertyParm("c", Val).
1318
1319cre_PropertyParm_c(ip4, Base, TTL) ->
1320    cre_PropertyParm_c("IP4", Base, i2s(TTL));
1321cre_PropertyParm_c(AddrType, Base, TTL)
1322  when is_list(AddrType) and
1323       is_list(Base)     and
1324       is_list(TTL) ->
1325    Val = "IN " ++ AddrType ++ " " ++ Base ++ "/" ++ TTL,
1326    cre_PropertyParm("c", Val).
1327
1328cre_PropertyParm_c(ip4, Base, TTL, NumOf) ->
1329    cre_PropertyParm_c("IP4", Base, i2s(TTL), i2s(NumOf));
1330cre_PropertyParm_c(AddrType, Base, TTL, NumOf)
1331  when is_list(AddrType) and
1332       is_list(Base)     and
1333       is_list(TTL)      and
1334       is_list(NumOf) ->
1335    Val =
1336	"IN " ++ AddrType ++ " " ++ Base ++ "/" ++ TTL ++ "/" ++ NumOf,
1337    cre_PropertyParm("c", Val).
1338
1339
1340cre_sdp_c(AddrType, ConnAddr) ->
1341    cre_sdp_c(in, AddrType, ConnAddr).
1342
1343cre_sdp_c(NetType, AddrType, ConnAddr) ->
1344    #megaco_sdp_c{network_type    = NetType,
1345		  address_type    = AddrType,
1346		  connection_addr = ConnAddr}.
1347
1348
1349cre_PropertyParm_v(Version) when is_integer(Version) ->
1350    cre_PropertyParm_v(integer_to_list(Version));
1351cre_PropertyParm_v(Version) when is_list(Version) ->
1352    cre_PropertyParm("v", Version).
1353
1354cre_sdp_v(Version) ->
1355    #megaco_sdp_v{version = Version}.
1356
1357
1358cre_PropertyParm(Name, Val) when is_list(Name) and is_list(Val) ->
1359    #'PropertyParm'{name = Name, value = [Val]}.
1360
1361
1362val(Vals) ->
1363    val(Vals, " ").
1364val([Head|Tail], Sep) ->
1365    lists:foldl(fun(E, S) -> S ++ Sep ++ E end, Head, Tail).
1366
1367i2s(I) when is_integer(I) ->
1368    integer_to_list(I);
1369i2s(S) when is_list(S) ->
1370    S.
1371
1372
1373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1374
1375%% p(F) ->
1376%%     p(F, []).
1377
1378p(F, A) ->
1379    p(get(sname), F, A).
1380
1381p(S, F, A) when is_list(S) ->
1382    io:format("*** [~s] ~p ~s ***"
1383	      "~n   " ++ F ++ "~n",
1384	      [?FTS(), self(), S | A]);
1385p(_S, F, A) ->
1386    io:format("*** [~s] ~p *** "
1387	      "~n   " ++ F ++ "~n",
1388	      [?FTS(), self() | A]).
1389
1390
1391