Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 1 | % ITU-T Q.704 (MTP Level 3) coding / decoding |
| 2 | |
| 3 | % (C) 2011 by Harald Welte <laforge@gnumonks.org> |
| 4 | % |
| 5 | % All Rights Reserved |
| 6 | % |
| 7 | % This program is free software; you can redistribute it and/or modify |
| 8 | % it under the terms of the GNU Affero General Public License as |
| 9 | % published by the Free Software Foundation; either version 3 of the |
| 10 | % License, or (at your option) any later version. |
| 11 | % |
| 12 | % This program is distributed in the hope that it will be useful, |
| 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | % GNU General Public License for more details. |
| 16 | % |
| 17 | % You should have received a copy of the GNU Affero General Public License |
| 18 | % along with this program. If not, see <http://www.gnu.org/licenses/>. |
Harald Welte | f8bf032 | 2012-04-16 13:10:47 +0200 | [diff] [blame^] | 19 | % |
| 20 | % Additional Permission under GNU AGPL version 3 section 7: |
| 21 | % |
| 22 | % If you modify this Program, or any covered work, by linking or |
| 23 | % combining it with runtime libraries of Erlang/OTP as released by |
| 24 | % Ericsson on http://www.erlang.org (or a modified version of these |
| 25 | % libraries), containing parts covered by the terms of the Erlang Public |
| 26 | % License (http://www.erlang.org/EPLICENSE), the licensors of this |
| 27 | % Program grant you additional permission to convey the resulting work |
| 28 | % without the need to license the runtime libraries of Erlang/OTP under |
| 29 | % the GNU Affero General Public License. Corresponding Source for a |
| 30 | % non-source form of such a combination shall include the source code |
| 31 | % for the parts of the runtime libraries of Erlang/OTP used as well as |
| 32 | % that of the covered work. |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 33 | |
| 34 | -module(mtp3_codec). |
| 35 | -author('Harald Welte <laforge@gnumonks.org>'). |
| 36 | -include("mtp3.hrl"). |
| 37 | |
Harald Welte | 1180b7c | 2012-01-25 01:28:56 +0100 | [diff] [blame] | 38 | -export([parse_mtp3_msg/1, encode_mtp3_msg/1, invert_rout_lbl/1]). |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 39 | |
Harald Welte | 5272527 | 2011-04-02 16:48:50 +0200 | [diff] [blame] | 40 | -compile({parse_transform, exprecs}). |
| 41 | -export_records([mtp3_routing_label, mtp3_msg]). |
| 42 | |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 43 | % Parse standard routing label according to Section 2.2 of ITU-T Q.704 |
| 44 | parse_mtp3_routing_label(_, LabelBin) when is_binary(LabelBin) -> |
Harald Welte | 0924436 | 2012-01-16 21:39:48 +0100 | [diff] [blame] | 45 | % we need to swap the four bytes and then parse the fields |
| 46 | <<Label32:32/little, Remain/binary>> = LabelBin, |
| 47 | LabelRev = <<Label32:32/big>>, |
| 48 | <<Sls:4/big, Dpc:14/big, Opc:14/big>> = LabelRev, |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 49 | {ok, #mtp3_routing_label{sig_link_sel = Sls, origin_pc = Opc, dest_pc = Dpc}, Remain}. |
| 50 | |
| 51 | parse_mtp3_msg(DataBin) when is_binary(DataBin) -> |
| 52 | <<NetInd:2, 0:2, ServiceInd:4, Remain/binary>> = DataBin, |
| 53 | {ok, RoutLbl, Payload} = parse_mtp3_routing_label(ServiceInd, Remain), |
Harald Welte | 642a68b | 2012-01-16 15:59:27 +0100 | [diff] [blame] | 54 | PayloadDec = decode_payload(ServiceInd, Payload), |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 55 | #mtp3_msg{network_ind = NetInd, service_ind = ServiceInd, routing_label = RoutLbl, |
Harald Welte | 642a68b | 2012-01-16 15:59:27 +0100 | [diff] [blame] | 56 | payload = PayloadDec}. |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 57 | |
| 58 | |
Harald Welte | eecba25 | 2011-12-08 12:02:02 +0100 | [diff] [blame] | 59 | encode_mtp3_routing_label(#mtp3_routing_label{sig_link_sel = Sls, origin_pc = OpcIn, |
| 60 | dest_pc = DpcIn}) -> |
| 61 | Opc = osmo_util:pointcode2int(OpcIn), |
| 62 | Dpc = osmo_util:pointcode2int(DpcIn), |
Harald Welte | 0924436 | 2012-01-16 21:39:48 +0100 | [diff] [blame] | 63 | % we need to swap the four bytes after encoding the fields |
| 64 | <<Label32:32/little>> = <<Sls:4/big, Dpc:14/big, Opc:14/big>>, |
| 65 | <<Label32:32/big>>. |
Harald Welte | eecba25 | 2011-12-08 12:02:02 +0100 | [diff] [blame] | 66 | |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 67 | encode_mtp3_msg(#mtp3_msg{network_ind = NetInd, service_ind = ServiceInd, |
| 68 | routing_label = RoutLbl, payload = Payload}) -> |
| 69 | RoutLblBin = encode_mtp3_routing_label(RoutLbl), |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 70 | PayloadBin = payload_to_binary(ServiceInd, Payload), |
Harald Welte | 642a68b | 2012-01-16 15:59:27 +0100 | [diff] [blame] | 71 | <<NetInd:2, 0:2, ServiceInd:4, RoutLblBin/binary, PayloadBin/binary>>. |
| 72 | |
| 73 | |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 74 | decode_payload(?MTP3_SERV_MTN, Payload) -> |
Harald Welte | e3b02ed | 2012-01-16 22:04:44 +0100 | [diff] [blame] | 75 | <<H1:4, H0:4, Len:4, 0:4, TP/binary>> = Payload, |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 76 | #mtp3mg_msg{h0 = H0, h1 = H1, payload = TP}; |
| 77 | decode_payload(?MTP3_SERV_MGMT, Payload) -> |
Harald Welte | e3b02ed | 2012-01-16 22:04:44 +0100 | [diff] [blame] | 78 | <<H1:4, H0:4, Remain/binary>> = Payload, |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 79 | #mtp3mg_msg{h0 = H0, h1 = H1, payload = Payload}; |
Harald Welte | 642a68b | 2012-01-16 15:59:27 +0100 | [diff] [blame] | 80 | decode_payload(_, Payload) -> |
| 81 | Payload. |
| 82 | |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 83 | payload_to_binary(?MTP3_SERV_MTN, #mtp3mg_msg{h0=H0, h1=H1, payload=TP}) -> |
Harald Welte | 642a68b | 2012-01-16 15:59:27 +0100 | [diff] [blame] | 84 | Len = byte_size(TP), |
Harald Welte | e3b02ed | 2012-01-16 22:04:44 +0100 | [diff] [blame] | 85 | <<H1:4, H0:4, Len:4, 0:4, TP/binary>>; |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 86 | payload_to_binary(?MTP3_SERV_MGMT, #mtp3mg_msg{h0=H0, h1=H1, payload=Payload}) -> |
Harald Welte | e3b02ed | 2012-01-16 22:04:44 +0100 | [diff] [blame] | 87 | <<H1:4, H0:4, Payload/binary>>; |
Harald Welte | 429456f | 2012-01-16 20:03:37 +0100 | [diff] [blame] | 88 | payload_to_binary(_, Whatever) -> |
Harald Welte | 642a68b | 2012-01-16 15:59:27 +0100 | [diff] [blame] | 89 | Whatever. |
Harald Welte | 1fbcd1c | 2011-01-15 20:51:53 +0100 | [diff] [blame] | 90 | |
Harald Welte | 1180b7c | 2012-01-25 01:28:56 +0100 | [diff] [blame] | 91 | |
| 92 | invert_rout_lbl(L = #mtp3_routing_label{origin_pc = Opc, dest_pc = Dpc}) -> |
| 93 | L#mtp3_routing_label{origin_pc = Dpc, dest_pc = Opc}. |