Home » Eclipse Projects » Eclipse Titan » Problems encoding SCCP LUDT (PDU_SCCP_LongUnitdata) with POINTERTO
Problems encoding SCCP LUDT (PDU_SCCP_LongUnitdata) with POINTERTO [message #1861089] |
Tue, 19 September 2023 19:25 |
Pau Espin Pedrol Messages: 14 Registered: November 2021 |
Junior Member |
|
|
Hi, I'm currently writing a test in TTCN3 which uses titan.ProtocolEmulations.SCCP [1] and I noticed the generated packet contains wrong pointer(1,2,3,4) values.
The test essentially submits an SCCP DULT with random data payload, something like:
template (value) PDU_SCCP ts_SCCP_LUDT(SCCP_PAR_Address calling, SCCP_PAR_Address called,
template (value) octetstring data,
template (value) BIT4 msg_hdl := '0000'B,
template (value) integer hop_ctr := 16) := {
longudata := {
messageType := ludt,
protClass := {'0000'B, msg_hdl},
hopCounter := hop_ctr,
pointer1 := 0, /* overwritten */
pointer2 := 0, /* overwritten */
pointer3 := 0, /* overwritten */
pointer4 := 0, /* overwritten */
calledPAddress := ConvertASPAddressToEncodedAddress_itu(called),
callingPAddress := ConvertASPAddressToEncodedAddress_itu(calling),
longData := {
paramLength := 0,
data := data
},
optionalPart := omit,
eop := omit
}
}
testcase TC_process_rx_ludt() runs on SCCP_Test_RAW_CT {
var SCCP_PAR_Address calling, called;
var octetstring data := f_rnd_octstring(1000);
f_init_raw(mp_sccp_cfg[0]);
f_sleep(1.0);
called := valueof(ts_SccpAddr_PC_SSN(mp_sccp_cfg[0].peer_pc, mp_sccp_cfg[0].peer_ssn,
mp_sccp_cfg[0].sio, mp_sccp_cfg[0].sccp_service_type));
calling := valueof(ts_SccpAddr_PC_SSN(mp_sccp_cfg[0].own_pc, mp_sccp_cfg[0].own_ssn,
mp_sccp_cfg[0].sio, mp_sccp_cfg[0].sccp_service_type)
f_send_sccp(ts_SCCP_XUDT(calling, called, data));
}
I think the other related types generate correct output (UDT, XUDT). The main difference between those and LUDT are:
* Pointers span 2 bytes instead of 1 (LIN2 vs LIN1)
* SCCP_param_LongData is used instead of SCCP_param_Data (which also has inside a length of 2 bytes instead of 1).
If I check with wireshark a packet I got from a production network, I see the following (see Pointer values):
Signalling Connection Control Part
Message Type: Long Unitdata (0x13)
.... 0000 = Class: 0x0
0000 .... = Message handling: No special options (0x0)
Hop Counter: 0x0f
Pointer to first Mandatory Variable parameter: 7
Pointer to second Mandatory Variable parameter: 10
Pointer to third Mandatory Variable parameter: 13
Pointer to Optional parameter: 0
Called Party address (4 bytes)
Address Indicator
0... .... = Reserved for national use: 0x0
.1.. .... = Routing Indicator: Route on SSN (0x1)
..00 00.. = Global Title Indicator: No Global Title (0x0)
.... ..1. = SubSystem Number Indicator: SSN present (0x1)
.... ...1 = Point Code Indicator: Point Code present (0x1)
..00 0100 1100 0100 = PC: 1220
SubSystem Number: RANAP (142)
[Linked to RANAP]
Calling Party address (4 bytes)
Address Indicator
0... .... = Reserved for national use: 0x0
.1.. .... = Routing Indicator: Route on SSN (0x1)
..00 00.. = Global Title Indicator: No Global Title (0x0)
.... ..1. = SubSystem Number Indicator: SSN present (0x1)
.... ...1 = Point Code Indicator: Point Code present (0x1)
..00 0011 1110 1001 = PC: 1001
SubSystem Number: RANAP (142)
[Linked to RANAP]
with the TTCN3 generate packet, I see the following (see how pointer values are 1 value higher):
Signalling Connection Control Part
Message Type: Long Unitdata (0x13)
.... 0000 = Class: 0x0
0000 .... = Message handling: No special options (0x0)
Hop Counter: 0x10
Pointer to first Mandatory Variable parameter: 8
Pointer to second Mandatory Variable parameter: 11
Pointer to third Mandatory Variable parameter: 14
Pointer to Optional parameter: 0
Called Party address (67 bytes)
Calling Party address (67 bytes)
As you can see, in the TTCN3 case, the values encoded into the pointer fields are wrong (1 too high), and hence wireshark starts decoding the "Called Party address" 1 byte to far and everything looks wrong.
The record type from titan.ProtocolEmulations.SCCP is this one:
type record PDU_SCCP_LongUnitdata
{
SCCP_param_MessageType messageType,
SCCP_param_ProtocolClass protClass,
SCCP_param_HopCounter hopCounter,
LIN2 pointer1,
LIN2 pointer2,
LIN2 pointer3,
LIN2 pointer4,
SCCP_param_CPartyAddressEnc calledPAddress,
SCCP_param_CPartyAddressEnc callingPAddress,
SCCP_param_LongData longData,
SCCP_ExtUnitdata_optionalPart optionalPart optional,
SCCP_param_EndOfOptionalParams eop optional
}
with { variant (pointer1) "POINTERTO(calledPAddress)";
variant (pointer2) "POINTERTO(callingPAddress)";
variant (pointer3) "POINTERTO(longData)";
variant (pointer4) "POINTERTO(optionalPart)";
variant "TAG (eop,paramName=con_SCCP_eop) "
}
I think there may be a bug with the implementation in titan of the POINTERTO with pointers spanning more than 1 byte. At least by looking at the reference guide [2] it's a big difficult to find out whether it starts counting after the entire pointer field, or from the start of it.
I tried playing with PTROFFSET to fix it, but I was unable to far. This change seems to leave the same behavior:
diff --git a/src/SCCP_Types.ttcn b/src/SCCP_Types.ttcn
index 2ae30e5..91f9e41 100644
--- a/src/SCCP_Types.ttcn
+++ b/src/SCCP_Types.ttcn
@@ -1249,9 +1249,13 @@ group PDUDefinitions
SCCP_param_EndOfOptionalParams eop optional
}
with { variant (pointer1) "POINTERTO(calledPAddress)";
+ variant (pointer1) "PTROFFSET(1)";
variant (pointer2) "POINTERTO(callingPAddress)";
+ variant (pointer2) "PTROFFSET(1)";
variant (pointer3) "POINTERTO(longData)";
+ variant (pointer3) "PTROFFSET(1)";
variant (pointer4) "POINTERTO(optionalPart)";
+ variant (pointer4) "PTROFFSET(1)";
variant "TAG (eop,paramName=con_SCCP_eop) "
}
This also leaves the same behavior:
diff --git a/src/SCCP_Types.ttcn b/src/SCCP_Types.ttcn
index 2ae30e5..91f9e41 100644
--- a/src/SCCP_Types.ttcn
+++ b/src/SCCP_Types.ttcn
@@ -1249,9 +1249,13 @@ group PDUDefinitions
SCCP_param_EndOfOptionalParams eop optional
}
with { variant (pointer1) "POINTERTO(calledPAddress)";
+ variant (pointer1) "PTROFFSET(pointer1)";
variant (pointer2) "POINTERTO(callingPAddress)";
+ variant (pointer2) "PTROFFSET(pointer2)";
variant (pointer3) "POINTERTO(longData)";
+ variant (pointer3) "PTROFFSET(pointer3)";
variant (pointer4) "POINTERTO(optionalPart)";
+ variant (pointer4) "PTROFFSET(pointer4)";
variant "TAG (eop,paramName=con_SCCP_eop) "
}
I also tried using PTROFFSET with the next field (eg variant (pointer2) "PTROFFSET(pointer1)"; , but then it goes wrong the other way: the value in the encoded packet becomes 1 byte too small.
I also tried using the following (which iiuc should works since the reference guide mentions "integers" are allowed), but ttcn3 fails to compile:
diff --git a/src/SCCP_Types.ttcn b/src/SCCP_Types.ttcn
index 2ae30e5..91f9e41 100644
--- a/src/SCCP_Types.ttcn
+++ b/src/SCCP_Types.ttcn
@@ -1249,9 +1249,13 @@ group PDUDefinitions
SCCP_param_EndOfOptionalParams eop optional
}
with { variant (pointer1) "POINTERTO(calledPAddress)";
+ variant (pointer1) "PTROFFSET(-1)";
variant (pointer2) "POINTERTO(callingPAddress)";
+ variant (pointer2) "PTROFFSET(-1)";
variant (pointer3) "POINTERTO(longData)";
+ variant (pointer3) "PTROFFSET(-1)";
variant (pointer4) "POINTERTO(optionalPart)";
+ variant (pointer4) "PTROFFSET(-1)";
variant "TAG (eop,paramName=con_SCCP_eop) "
}
SCCP_Types.ttcn: In TTCN-3 module `SCCP_Types':
SCCP_Types.ttcn:97.1-67: In external function definition `enc_PDU_SCCP':
SCCP_Types.ttcn:97.31-48: In formal parameter list:
SCCP_Types.ttcn:97.33-47: In parameter `pdu':
SCCP_Types.ttcn:1314.3-1337.3: In type definition `PDU_SCCP':
SCCP_Types.ttcn:1332.5-49: In union field `longudata':
SCCP_Types.ttcn:1236.3-1250.4: In type definition `PDU_SCCP_LongUnitdata':
SCCP_Types.ttcn:1252.41: error: in variant attribute, at or before token `-': syntax error
SCCP_Types.ttcn:1254.41: error: in variant attribute, at or before token `-': syntax error
SCCP_Types.ttcn:1256.41: error: in variant attribute, at or before token `-': syntax error
SCCP_Types.ttcn:1258.41: error: in variant attribute, at or before token `-': syntax error
So at least I'd say the reference guide or the code has to be improved/fixes for the negative value scenario.
Any ideas or support is welcome. I attach the correct packet (from production network) and the TTCN3 generated one (with a random payload of 1000 bytes).
[1] https://gitlab.eclipse.org/eclipse/titan/titan.ProtocolEmulations.SCCP
[2] https://download.eclipse.org/titan/ReferenceGuide.pdf
[Updated on: Tue, 19 September 2023 19:35] Report message to a moderator
|
|
|
Re: Problems encoding SCCP LUDT (PDU_SCCP_LongUnitdata) with POINTERTO [message #1861091 is a reply to message #1861089] |
Tue, 19 September 2023 19:58 |
Pau Espin Pedrol Messages: 14 Registered: November 2021 |
Junior Member |
|
|
I have the feeling the variant (pointer1) "PTROFFSET(1)"; is somehow not applied to the generated C++ code. I'm using titan v8.3.0, and I see titan.core compiler in that version does for instance:
if(raw_options[i].pointerto){ /* store the start of pointed field*/
src=mputprintf(src,
" start_of_field%d=(int)field_%s%s+%d?1:-1;\n"
,sdef->elements[i].raw.pointerto
,sdef->elements[i].name,sdef->elements[i].isOptional?"()":""
,sdef->elements[i].raw.ptroffset
);
}
But looking at the generated code, sdef->elements[i].raw.ptroffset seems to be 0:
int PDU__SCCP__LongUnitdataService::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
...
start_of_field7=(int)field_pointer1+0?1:-1;
...
}
|
|
| | | | | | | | |
Goto Forum:
Current Time: Wed Oct 09 17:16:47 GMT 2024
Powered by FUDForum. Page generated in 0.03962 seconds
|