1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2003-2016. 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 : Handle ASN.1 BER encoding of Megaco/H.248
24%%----------------------------------------------------------------------
25
26-module(megaco_ber_bin_drv_encoder).
27
28-behaviour(megaco_encoder).
29
30-export([encode_message/3, decode_message/3,
31	 decode_mini_message/3,
32
33	 encode_transaction/3,
34	 encode_action_requests/3,
35	 encode_action_request/3,
36	 encode_action_reply/3,
37
38	 version_of/2]).
39
40%% Backward compatible functions:
41-export([encode_message/2, decode_message/2]).
42
43-include_lib("megaco/src/engine/megaco_message_internal.hrl").
44
45-define(V1_ASN1_MOD,     megaco_ber_bin_drv_media_gateway_control_v1).
46-define(V2_ASN1_MOD,     megaco_ber_bin_drv_media_gateway_control_v2).
47-define(V3_ASN1_MOD,     megaco_ber_bin_drv_media_gateway_control_v3).
48-define(PREV3A_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_prev3a).
49-define(PREV3B_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_prev3b).
50-define(PREV3C_ASN1_MOD, megaco_ber_bin_drv_media_gateway_control_prev3c).
51
52-define(V1_TRANS_MOD,     megaco_binary_transformer_v1).
53-define(V2_TRANS_MOD,     megaco_binary_transformer_v2).
54-define(V3_TRANS_MOD,     megaco_binary_transformer_v3).
55-define(PREV3A_TRANS_MOD, megaco_binary_transformer_prev3a).
56-define(PREV3B_TRANS_MOD, megaco_binary_transformer_prev3b).
57-define(PREV3C_TRANS_MOD, megaco_binary_transformer_prev3c).
58
59-define(BIN_LIB, megaco_binary_encoder_lib).
60
61
62%%----------------------------------------------------------------------
63%% Detect (check) which version a message is
64%% Return {ok, Version} | {error, Reason}
65%%----------------------------------------------------------------------
66
67version_of([{version3,v3}|EC], Binary) ->
68    Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
69    ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
70version_of([{version3,prev3c}|EC], Binary) ->
71    Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
72    ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
73version_of([{version3,prev3b}|EC], Binary) ->
74    Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
75    ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
76version_of([{version3,prev3a}|EC], Binary) ->
77    Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
78    ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders);
79version_of(EC, Binary) ->
80    Decoders = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
81    ?BIN_LIB:version_of(EC, Binary, dynamic, Decoders).
82
83
84%%----------------------------------------------------------------------
85%% Convert a 'MegacoMessage' record into a binary
86%% Return {ok, Binary} | {error, Reason}
87%%----------------------------------------------------------------------
88
89
90encode_message(EC,
91	       #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) ->
92    encode_message(EC, V, MegaMsg).
93
94encode_message([{version3,_}|EC], 1, MegaMsg) ->
95    ?BIN_LIB:encode_message(EC, MegaMsg, ?V1_ASN1_MOD, ?V1_TRANS_MOD, io_list);
96encode_message(EC, 1, MegaMsg) ->
97    ?BIN_LIB:encode_message(EC, MegaMsg, ?V1_ASN1_MOD, ?V1_TRANS_MOD, io_list);
98encode_message([{version3,_}|EC], 2, MegaMsg) ->
99    ?BIN_LIB:encode_message(EC, MegaMsg, ?V2_ASN1_MOD, ?V2_TRANS_MOD, io_list);
100encode_message(EC, 2, MegaMsg) ->
101    ?BIN_LIB:encode_message(EC, MegaMsg, ?V2_ASN1_MOD, ?V2_TRANS_MOD, io_list);
102encode_message([{version3,v3}|EC], 3, MegaMsg) ->
103    ?BIN_LIB:encode_message(EC, MegaMsg, ?V3_ASN1_MOD, ?V3_TRANS_MOD, io_list);
104encode_message([{version3,prev3c}|EC], 3, MegaMsg) ->
105    ?BIN_LIB:encode_message(EC, MegaMsg,
106			    ?PREV3C_ASN1_MOD, ?PREV3C_TRANS_MOD, io_list);
107encode_message([{version3,prev3b}|EC], 3, MegaMsg) ->
108    ?BIN_LIB:encode_message(EC, MegaMsg,
109			    ?PREV3B_ASN1_MOD, ?PREV3B_TRANS_MOD, io_list);
110encode_message([{version3,prev3a}|EC], 3, MegaMsg) ->
111    ?BIN_LIB:encode_message(EC, MegaMsg,
112			    ?PREV3A_ASN1_MOD, ?PREV3A_TRANS_MOD, io_list);
113encode_message(EC, 3, MegaMsg) ->
114    ?BIN_LIB:encode_message(EC, MegaMsg, ?V3_ASN1_MOD, ?V3_TRANS_MOD, io_list).
115
116
117%%----------------------------------------------------------------------
118%% Convert a transaction (or transactions in the case of ack) record(s)
119%% into a binary
120%% Return {ok, Binary} | {error, Reason}
121%%----------------------------------------------------------------------
122
123encode_transaction(EC, 1, Trans) ->
124    %%     ?BIN_LIB:encode_transaction(EC, Trans,
125    %% 					     ?V1_ASN1_MOD,
126    %% 					     ?V1_TRANS_MOD,
127    %% 					     io_list);
128    {error, not_implemented};
129encode_transaction(EC, 2, Trans) ->
130    %%     ?BIN_LIB:encode_transaction(EC, Trans,
131    %% 					     ?V2_ASN1_MOD,
132    %% 					     ?V2_TRANS_MOD,
133    %% 					     io_list).
134    {error, not_implemented};
135encode_transaction(EC, 3, Trans) ->
136    %%     ?BIN_LIB:encode_transaction(EC, Trans,
137    %% 					     ?V3_ASN1_MOD,
138    %% 					     ?V3_TRANS_MOD,
139    %% 					     io_list).
140    {error, not_implemented}.
141
142
143%%----------------------------------------------------------------------
144%% Convert a list of ActionRequest record's into a binary
145%% Return {ok, DeepIoList} | {error, Reason}
146%%----------------------------------------------------------------------
147encode_action_requests(EC, 1, ActReqs) when is_list(ActReqs) ->
148    %%     ?BIN_LIB:encode_action_requests(EC, ActReqs,
149    %% 						 ?V1_ASN1_MOD,
150    %% 						 ?V1_TRANS_MOD,
151    %% 						 io_list);
152    {error, not_implemented};
153encode_action_requests(EC, 2, ActReqs) when is_list(ActReqs) ->
154    %%     ?BIN_LIB:encode_action_requests(EC, ActReqs,
155    %% 						 ?V2_ASN1_MOD,
156    %% 						 ?V2_TRANS_MOD,
157    %% 						 io_list).
158    {error, not_implemented};
159encode_action_requests(EC, 3, ActReqs) when is_list(ActReqs) ->
160    %%     ?BIN_LIB:encode_action_requests(EC, ActReqs,
161    %% 						 ?V3_ASN1_MOD,
162    %% 						 ?V3_TRANS_MOD,
163    %% 						 io_list).
164    {error, not_implemented}.
165
166
167%%----------------------------------------------------------------------
168%% Convert a ActionRequest record into a binary
169%% Return {ok, DeepIoList} | {error, Reason}
170%%----------------------------------------------------------------------
171encode_action_request(EC, 1, ActReq) ->
172    %%     ?BIN_LIB:encode_action_request(EC, ActReq,
173    %% 						?V1_ASN1_MOD,
174    %% 						?V1_TRANS_MOD,
175    %% 						io_list);
176    {error, not_implemented};
177encode_action_request(EC, 2, ActReq) ->
178    %%     ?BIN_LIB:encode_action_request(EC, ActReq,
179    %% 						?V2_ASN1_MOD,
180    %% 						?V2_TRANS_MOD,
181    %% 						io_list).
182    {error, not_implemented};
183encode_action_request(EC, 3, ActReq) ->
184    %%     ?BIN_LIB:encode_action_request(EC, ActReq,
185    %% 						?V3_ASN1_MOD,
186    %% 						?V3_TRANS_MOD,
187    %% 						io_list).
188    {error, not_implemented}.
189
190
191%%----------------------------------------------------------------------
192%% Convert a action reply into a deep io list
193%% Not yest supported by this binary codec!
194%% Return {ok, DeepIoList} | {error, Reason}
195%%----------------------------------------------------------------------
196
197encode_action_reply(_EC, _V, _AcionReply) ->
198    {error, not_implemented}.
199
200
201%%----------------------------------------------------------------------
202%% Convert a binary into a 'MegacoMessage' record
203%% Return {ok, MegacoMessageRecord} | {error, Reason}
204%%----------------------------------------------------------------------
205
206%% Old decode function
207decode_message(EC, Binary) ->
208    decode_message(EC, 1, Binary).
209
210%% Select from message
211%% This does not work at the moment so, we use version 1 for this
212decode_message([{version3,v3}|EC], dynamic, Binary) ->
213    Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
214	    {?V2_ASN1_MOD, ?V2_TRANS_MOD},
215	    {?V3_ASN1_MOD, ?V3_TRANS_MOD}],
216    ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
217decode_message([{version3,prev3c}|EC], dynamic, Binary) ->
218    Mods = [{?V1_ASN1_MOD,     ?V1_TRANS_MOD},
219	    {?V2_ASN1_MOD,     ?V2_TRANS_MOD},
220	    {?PREV3C_ASN1_MOD, ?PREV3C_TRANS_MOD}],
221    ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
222decode_message([{version3,prev3b}|EC], dynamic, Binary) ->
223    Mods = [{?V1_ASN1_MOD,     ?V1_TRANS_MOD},
224	    {?V2_ASN1_MOD,     ?V2_TRANS_MOD},
225	    {?PREV3B_ASN1_MOD, ?PREV3B_TRANS_MOD}],
226    ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
227decode_message([{version3,prev3a}|EC], dynamic, Binary) ->
228    Mods = [{?V1_ASN1_MOD,     ?V1_TRANS_MOD},
229	    {?V2_ASN1_MOD,     ?V2_TRANS_MOD},
230	    {?PREV3A_ASN1_MOD, ?PREV3A_TRANS_MOD}],
231    ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
232decode_message(EC, dynamic, Binary) ->
233    Mods = [{?V1_ASN1_MOD, ?V1_TRANS_MOD},
234	    {?V2_ASN1_MOD, ?V2_TRANS_MOD},
235	    {?V3_ASN1_MOD, ?V3_TRANS_MOD}],
236    ?BIN_LIB:decode_message_dynamic(EC, Binary, Mods, binary);
237
238decode_message([{version3,_}|EC], 1, Binary) ->
239    AsnMod   = ?V1_ASN1_MOD,
240    TransMod = ?V1_TRANS_MOD,
241    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
242decode_message(EC, 1, Binary) ->
243    AsnMod   = ?V1_ASN1_MOD,
244    TransMod = ?V1_TRANS_MOD,
245    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
246
247decode_message([{version3,_}|EC], 2, Binary) ->
248    AsnMod   = ?V2_ASN1_MOD,
249    TransMod = ?V2_TRANS_MOD,
250    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
251decode_message(EC, 2, Binary) ->
252    AsnMod   = ?V2_ASN1_MOD,
253    TransMod = ?V2_TRANS_MOD,
254    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
255
256decode_message([{version3,v3}|EC], 3, Binary) ->
257    AsnMod   = ?V3_ASN1_MOD,
258    TransMod = ?V3_TRANS_MOD,
259    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
260decode_message([{version3,prev3c}|EC], 3, Binary) ->
261    AsnMod   = ?PREV3C_ASN1_MOD,
262    TransMod = ?PREV3C_TRANS_MOD,
263    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
264decode_message([{version3,prev3b}|EC], 3, Binary) ->
265    AsnMod   = ?PREV3B_ASN1_MOD,
266    TransMod = ?PREV3B_TRANS_MOD,
267    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
268decode_message([{version3,prev3a}|EC], 3, Binary) ->
269    AsnMod   = ?PREV3A_ASN1_MOD,
270    TransMod = ?PREV3A_TRANS_MOD,
271    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
272decode_message(EC, 3, Binary) ->
273    AsnMod   = ?V3_ASN1_MOD,
274    TransMod = ?V3_TRANS_MOD,
275    ?BIN_LIB:decode_message(EC, Binary, AsnMod, TransMod, binary);
276
277
278decode_mini_message([{version3,v3}|EC], dynamic, Bin) ->
279    Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
280    ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
281decode_mini_message([{version3,prev3c}|EC], dynamic, Bin) ->
282    Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3C_ASN1_MOD],
283    ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
284decode_mini_message([{version3,prev3b}|EC], dynamic, Bin) ->
285    Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3B_ASN1_MOD],
286    ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
287decode_mini_message([{version3,prev3a}|EC], dynamic, Bin) ->
288    Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?PREV3A_ASN1_MOD],
289    ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
290decode_mini_message(EC, dynamic, Bin) ->
291    Mods = [?V1_ASN1_MOD, ?V2_ASN1_MOD, ?V3_ASN1_MOD],
292    ?BIN_LIB:decode_mini_message_dynamic(EC, Bin, Mods, binary);
293
294decode_mini_message([{version3,_}|EC], 1, Bin) ->
295    AsnMod = ?V1_ASN1_MOD,
296    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
297decode_mini_message(EC, 1, Bin) ->
298    AsnMod = ?V1_ASN1_MOD,
299    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
300decode_mini_message([{version3,_}|EC], 2, Bin) ->
301    AsnMod = ?V2_ASN1_MOD,
302    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
303decode_mini_message(EC, 2, Bin) ->
304    AsnMod = ?V2_ASN1_MOD,
305    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
306decode_mini_message([{version3,v3}|EC], 3, Bin) ->
307    AsnMod = ?V3_ASN1_MOD,
308    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
309decode_mini_message([{version3,prev3c}|EC], 3, Bin) ->
310    AsnMod = ?PREV3C_ASN1_MOD,
311    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
312decode_mini_message([{version3,prev3b}|EC], 3, Bin) ->
313    AsnMod = ?PREV3B_ASN1_MOD,
314    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
315decode_mini_message([{version3,prev3a}|EC], 3, Bin) ->
316    AsnMod = ?PREV3A_ASN1_MOD,
317    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary);
318decode_mini_message(EC, 3, Bin) ->
319    AsnMod = ?V3_ASN1_MOD,
320    ?BIN_LIB:decode_mini_message(EC, Bin, AsnMod, binary).
321