Harald Welte | c60e840 | 2011-03-08 23:02:32 +0100 | [diff] [blame] | 1 | -module(map_codec_tests). |
| 2 | -author('Harald Welte <laforge@gnumonks.org>'). |
| 3 | |
| 4 | -include_lib("eunit/include/eunit.hrl"). |
| 5 | |
| 6 | -include("map.hrl"). |
| 7 | -include_lib("osmo_ss7/include/isup.hrl"). |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 8 | -include_lib("osmo_ss7/include/m2ua.hrl"). |
| 9 | -include_lib("osmo_ss7/include/mtp3.hrl"). |
| 10 | -include_lib("osmo_ss7/include/sccp.hrl"). |
Harald Welte | c60e840 | 2011-03-08 23:02:32 +0100 | [diff] [blame] | 11 | |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 12 | % modified version of assertEqual() |
| 13 | -define(assertEqualArgs(Expect, Expr, Args), |
| 14 | ((fun (__X) -> |
| 15 | case (Expr) of |
| 16 | __X -> ok; |
| 17 | __V -> ?debugFmt("Expected: ~w~nValue: ~w~n", [__X, __V]), |
| 18 | .erlang:error({assertEqual_failed, |
| 19 | [{module, ?MODULE}, |
| 20 | {line, ?LINE}, |
| 21 | {expression, (??Expr)}, |
| 22 | {expected, __X}, |
| 23 | {value, __V}] ++ Args}) |
| 24 | end |
| 25 | end)(Expect))). |
| 26 | -define(_assertEqualArgs(Expect, Expr, Args), ?_test(?assertEqual(Expect, Expr, Args))). |
| 27 | |
Harald Welte | c60e840 | 2011-03-08 23:02:32 +0100 | [diff] [blame] | 28 | -define(TCAP_MSG_BIN, <<100,65,73,4,81,1,2,200,107,42,40,40,6,7,0,17,134,5,1,1,1,160,29,97,27,128,2,7,128,161,9,6,7,4,0,0,1,0,1,3,162,3,2,1,0,163,5,161,3,2,1,0,108,13,163,11,2,1,64,2,1,8,48,3,10,1,0>>). |
Harald Welte | 21c6b94 | 2011-04-16 20:14:38 +0200 | [diff] [blame] | 29 | -define(TCAP_MSG_DEC, {'end',{'MapSpecificPDUs_end',[81,1,2,200],{'EXTERNAL',{0,0,17,773,1,1,1},asn1_NOVALUE,asn1_NOVALUE, {'single-ASN1-type', [97,27,128,2,7,128,161,9,6,7,4,0,0,1,0,1,3,162,3,2,1,0,163,5,161,3,2,1,0]}},[{basicROS,{returnError,{'MapSpecificPDUs_end_components_SEQOF_basicROS_returnError',{present,64},{local,8},{'RoamingNotAllowedParam',plmnRoamingNotAllowed,asn1_NOVALUE,asn1_NOVALUE}}}}]}}). |
Harald Welte | c60e840 | 2011-03-08 23:02:32 +0100 | [diff] [blame] | 30 | |
| 31 | parse_test() -> |
| 32 | ?assertEqual(?TCAP_MSG_DEC, map_codec:parse_tcap_msg(?TCAP_MSG_BIN)). |
Harald Welte | 21c6b94 | 2011-04-16 20:14:38 +0200 | [diff] [blame] | 33 | encode_test() -> |
| 34 | ?assertEqual(?TCAP_MSG_BIN, map_codec:encode_tcap_msg(?TCAP_MSG_DEC)). |
Harald Welte | c60e840 | 2011-03-08 23:02:32 +0100 | [diff] [blame] | 35 | |
| 36 | -define(ADDR_DEC, #party_number{nature_of_addr_ind = ?ISUP_ADDR_NAT_INTERNATIONAL, |
| 37 | internal_net_num = undefined, |
| 38 | number_incompl_ind = undefined, |
| 39 | numbering_plan = 0, |
| 40 | present_restrict = undefined, |
| 41 | screening_ind = undefined, |
| 42 | phone_number = [1,2,3,4,5,6,7,8,9,0]}). |
| 43 | -define(ADDR_LIST, [144,33,67,101,135,9]). |
| 44 | |
| 45 | encode_addr_list_test() -> |
| 46 | ?assertEqual(?ADDR_LIST, map_codec:encode_addr_string(?ADDR_DEC)). |
| 47 | encode_addr_int_test() -> |
| 48 | AddrDec = ?ADDR_DEC, |
| 49 | ?assertEqual(?ADDR_LIST, map_codec:encode_addr_string(AddrDec#party_number{phone_number=1234567890})). |
| 50 | decode_addr_list_test() -> |
| 51 | ?assertEqual(?ADDR_DEC, map_codec:parse_addr_string(?ADDR_LIST)). |
| 52 | decode_addr_bin_test() -> |
| 53 | ?assertEqual(?ADDR_DEC, map_codec:parse_addr_string(list_to_binary(?ADDR_LIST))). |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 54 | |
| 55 | |
| 56 | pcap_parse_test_() -> |
| 57 | { timeout, 5*60, [ fun pcap_parse_t/0 ] }. |
| 58 | |
| 59 | % parser test for real-world MAP/TCAP data |
| 60 | pcap_parse_t() -> |
| 61 | Args = [{rewrite_fn, fun pcap_cb/5}], |
| 62 | File = "../priv/map.pcap", |
| 63 | case file:read_file_info(File) of |
| 64 | {ok, _Info} -> |
| 65 | {ok, NrPkts} = ?debugTime("PCAP", osmo_ss7_pcap:pcap_apply(File, "", Args)), |
| 66 | ?debugFmt("Parsed ~p PCAP packets~n", [NrPkts]); |
| 67 | {error, _Reason} -> |
| 68 | ?debugFmt("Skipping PCAP based tests as no ~p could be found~n", |
| 69 | [File]) |
| 70 | end. |
| 71 | |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 72 | pcap_cb(sctp, _From, Path, 2, DataBin) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 73 | {ok, M2ua} = m2ua_codec:parse_m2ua_msg(DataBin), |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 74 | M2uaReenc = m2ua_codec:encode_m2ua_msg(M2ua), |
| 75 | ?assertEqualArgs(DataBin, M2uaReenc, [{layer, m2ua}, {path, Path}]), |
| 76 | handle_m2ua(M2ua, Path), |
| 77 | DataBin. |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 78 | |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 79 | handle_m2ua(M2ua = #m2ua_msg{msg_class = ?M2UA_MSGC_MAUP, |
| 80 | msg_type = ?M2UA_MAUP_MSGT_DATA, |
| 81 | parameters = Params}, Path) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 82 | {_Len, M2uaPayload} = proplists:get_value(16#300, Params), |
| 83 | Mtp3 = mtp3_codec:parse_mtp3_msg(M2uaPayload), |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 84 | Mtp3Reenc = mtp3_codec:encode_mtp3_msg(Mtp3), |
| 85 | ?assertEqualArgs(M2uaPayload, Mtp3Reenc, [{layer, mtp3}, {path, Path}]), |
| 86 | handle_mtp3(Mtp3, Path ++ [M2ua]); |
| 87 | handle_m2ua(M2ua = #m2ua_msg{}, _Path) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 88 | M2ua. |
| 89 | |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 90 | handle_mtp3(Mtp3 = #mtp3_msg{service_ind = ?MTP3_SERV_SCCP, |
| 91 | payload = Payload}, Path) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 92 | {ok, SccpDec} = sccp_codec:parse_sccp_msg(Payload), |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 93 | SccpReenc = sccp_codec:encode_sccp_msg(SccpDec), |
| 94 | % We cannot assume that the data is equal due to SCCP allowing |
| 95 | % different encodings of the same data. instead we re-decode |
| 96 | {ok, SccpReencDec} = sccp_codec:parse_sccp_msg(SccpReenc), |
| 97 | ?assertEqualArgs(SccpDec, SccpReencDec, [{layer, sccp}, {path, Path}]), |
| 98 | handle_sccp(SccpDec, Path ++ [Mtp3]); |
| 99 | handle_mtp3(Mtp3 = #mtp3_msg{}, _Path) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 100 | Mtp3. |
| 101 | |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 102 | handle_sccp(S = #sccp_msg{msg_type = ?SCCP_MSGT_UDT, parameters = Params}, Path) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 103 | UserData = proplists:get_value(user_data, Params), |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 104 | PathOut = Path ++ [S], |
| 105 | case map_codec:parse_tcap_msg(UserData) of |
| 106 | {error, Error} -> |
| 107 | ErrTuple = {Error, erlang:get_stacktrace(), []}, |
| 108 | ?debugFmt("Path: ~p~nMAP Decode Error: ~w~n", [PathOut, ErrTuple]), |
| 109 | erlang:error(ErrTuple); |
| 110 | MapDec -> |
Harald Welte | 21c6b94 | 2011-04-16 20:14:38 +0200 | [diff] [blame] | 111 | %?debugFmt("~w~n", [MapDec]), |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 112 | case map_codec:encode_tcap_msg(MapDec) of |
| 113 | {error, Error} -> |
| 114 | ErrTuple = {Error, erlang:get_stacktrace(), [{map_dec, MapDec}]}, |
| 115 | ?debugFmt("Path: ~p~nMAP Encode Error: ~w~n", [PathOut, ErrTuple]), |
| 116 | erlang:error(ErrTuple); |
| 117 | MapReenc -> |
Harald Welte | 21c6b94 | 2011-04-16 20:14:38 +0200 | [diff] [blame] | 118 | %?assertEqualArgs(UserData, MapReenc, [{layer, map}, {path, Path}]), |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 119 | MapReencDec = map_codec:parse_tcap_msg(MapReenc), |
| 120 | ?assertEqualArgs(MapDec, MapReencDec, [{layer, map}, {path, Path}]) |
| 121 | end |
| 122 | end, |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 123 | S; |
Harald Welte | 3575d44 | 2011-03-12 10:23:10 +0100 | [diff] [blame] | 124 | handle_sccp(S = #sccp_msg{}, _Path) -> |
Harald Welte | 49525f8 | 2011-03-11 18:47:23 +0100 | [diff] [blame] | 125 | S. |