Removed SS7 route MSU size upper boundary.

Fixed SCCP LUDT maximum data length calculation.


git-svn-id: http://voip.null.ro/svn/yate@4851 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
andrei 2012-02-08 09:35:30 +00:00
parent 664ecac9d0
commit a341b02137
3 changed files with 29 additions and 25 deletions

View File

@ -514,9 +514,9 @@
; For example for 2 links shift = 1. ; For example for 2 links shift = 1.
; A value of 8 or higher disables load balancing. ; A value of 8 or higher disables load balancing.
; ;
; Size represents the maximum data size that can be transported on this route. ; Size represents the maximum MSU size that can be transported on this route.
; The default vaue is 272 -> maximum MSU size on TDM. ; The default vaue is 272 -> maximum MSU size on TDM.
; If the route can transport more data, a value up to 3904 should be set to ; If the route can transport more data, a value up to 4000 should be set to
; avoid SCCP message fragmentation. ; avoid SCCP message fragmentation.
; ;
; Example: route=ITU,2-2-2,100,1,272 ; Example: route=ITU,2-2-2,100,1,272
@ -529,9 +529,9 @@
; ;
; The priority is always zero so an adjacent route will always match first. ; The priority is always zero so an adjacent route will always match first.
; ;
; Size represents the maximum data size that can be transported on this route. ; Size represents the maximum MSU size that can be transported on this route.
; The default vaue is 272 -> maximum MSU size on TDM. ; The default vaue is 272 -> maximum MSU size on TDM.
; If the route can transport more data, a value up to 3904 should be set to ; If the route can transport more data, a value up to 4000 should be set to
; avoid SCCP message fragmentation ; avoid SCCP message fragmentation
; ;
; Example: adjacent=ANSI,40-50-60,272 ; Example: adjacent=ANSI,40-50-60,272

View File

@ -30,7 +30,6 @@
using namespace TelEngine; using namespace TelEngine;
#define MAX_TDM_DATA_SIZE 272 #define MAX_TDM_DATA_SIZE 272
#define MAX_SIGTRAN_DATA_SIZE 3904 // Maximum ANSI LUDT(SCCP) length
static const TokenDict s_dict_control[] = { static const TokenDict s_dict_control[] = {
{ "show", SS7MTP3::Status }, { "show", SS7MTP3::Status },
@ -220,11 +219,6 @@ bool SS7Layer3::buildRoutes(const NamedList& params)
maxLength,MAX_TDM_DATA_SIZE); maxLength,MAX_TDM_DATA_SIZE);
maxLength = MAX_TDM_DATA_SIZE; maxLength = MAX_TDM_DATA_SIZE;
} }
if (maxLength > MAX_SIGTRAN_DATA_SIZE) {
Debug(this,DebugNote,"MaxDataLength is too big %d. Setting it to %d",
maxLength,MAX_SIGTRAN_DATA_SIZE);
maxLength = MAX_SIGTRAN_DATA_SIZE;
}
} while (false); } while (false);
TelEngine::destruct(route); TelEngine::destruct(route);
unsigned int packed = pc.pack(type); unsigned int packed = pc.pack(type);

View File

@ -43,6 +43,9 @@ using namespace TelEngine;
// Minimum data size in a SCCP message // Minimum data size in a SCCP message
#define MIN_DATA_SIZE 2 #define MIN_DATA_SIZE 2
#define MAX_DATA_ITU 3952
#define MAX_DATA_ANSI 3904
static const char* s_userMutexName = "SCCPUserTransport"; static const char* s_userMutexName = "SCCPUserTransport";
static const char* s_sccpMutexName = "SCCPUserList"; static const char* s_sccpMutexName = "SCCPUserList";
static const char* s_managementMutexName = "SCCPManagement"; static const char* s_managementMutexName = "SCCPManagement";
@ -3167,14 +3170,11 @@ void SS7SCCP::getMaxDataLen(const SS7MsgSCCP* msg, const SS7Label& label,
// Adjust maxLen to represent maximum data in the message. // Adjust maxLen to represent maximum data in the message.
unsigned int headerLength = 3; // MsgType + ProtocolClass unsigned int headerLength = 3; // MsgType + ProtocolClass
// Memorize pointer start to adjust data size. // Memorize pointer start to adjust data size.
unsigned int pointerLen = 1;
if (msg->type() == msg->isLongDataMessage())
pointerLen++;
unsigned int pointersStart = headerLength; unsigned int pointersStart = headerLength;
maxLen -= headerLength; maxLen -= headerLength;
// We have 3 mandatory variable parameters CallingAddress, CalledAddress, // We have 3 mandatory variable parameters CallingAddress, CalledAddress,
// and Data and the pointer to optional parameters // and Data and the pointer to optional parameters + 1 data length
headerLength += 4 * pointerLen; headerLength += 5;
headerLength += getAddressLength(msg->params(), "CalledPartyAddress"); headerLength += getAddressLength(msg->params(), "CalledPartyAddress");
headerLength += getAddressLength(msg->params(), "CallingPartyAddress"); headerLength += getAddressLength(msg->params(), "CallingPartyAddress");
ludt = 0; ludt = 0;
@ -3186,13 +3186,15 @@ void SS7SCCP::getMaxDataLen(const SS7MsgSCCP* msg, const SS7Label& label,
else else
udt = maxLen - sccpParamsSize; udt = maxLen - sccpParamsSize;
// Append optional parameters length // Append optional parameters length
headerLength += MAX_OPT_LEN; sccpParamsSize += MAX_OPT_LEN;
if (ludtSupport) { if (ludtSupport) {
unsigned int maxSupported = ITU() ? 3952 : 3904; unsigned int maxSupported = ITU() ? MAX_DATA_ITU : MAX_DATA_ANSI;
if (maxLen > maxSupported) if (maxLen < maxSupported) {
ludt = maxSupported - sccpParamsSize;
else
ludt = maxLen - sccpParamsSize; ludt = maxLen - sccpParamsSize;
ludt -= 5; // The pointers and data length are on 2 octets
} else
ludt = maxSupported;
} }
// 254 represents the maximum value that can be stored // 254 represents the maximum value that can be stored
if (maxLen < 254) if (maxLen < 254)
@ -3290,15 +3292,22 @@ int SS7SCCP::segmentMessage(SS7MsgSCCP* origMsg, const SS7Label& label, bool loc
DataBlock* data = origMsg->getData(); DataBlock* data = origMsg->getData();
if (!data) if (!data)
return -1; return -1;
// Verify if we should bother to send the message
if (data->length() > (ITU() ? MAX_DATA_ITU : MAX_DATA_ANSI)) {
Debug(this,DebugNote,
"Unable to send SCCP message! Data length (%d) is too long",
data->length());
return -1;
}
SS7MsgSCCP::Type msgType = origMsg->type(); SS7MsgSCCP::Type msgType = origMsg->type();
if (data->length() < udtLength && origMsg->canBeUDT()) { if (data->length() <= udtLength && origMsg->canBeUDT()) {
msgType = isSCLCMessage(msgType) ? SS7MsgSCCP::UDT : SS7MsgSCCP::UDTS; msgType = isSCLCMessage(msgType) ? SS7MsgSCCP::UDT : SS7MsgSCCP::UDTS;
dataLen = udtLength; dataLen = udtLength;
} else if (data->length() < xudtLength) { } else if (data->length() <= xudtLength) {
msgType = isSCLCMessage(msgType) ? SS7MsgSCCP::XUDT : SS7MsgSCCP::XUDTS; msgType = isSCLCMessage(msgType) ? SS7MsgSCCP::XUDT : SS7MsgSCCP::XUDTS;
dataLen = xudtLength; dataLen = xudtLength;
} else if (data->length() < ludtLength) { } else if (data->length() <= ludtLength) {
msgType = isSCLCMessage(msgType) ? SS7MsgSCCP::LUDT : SS7MsgSCCP::LUDTS; msgType = isSCLCMessage(msgType) ? SS7MsgSCCP::LUDT : SS7MsgSCCP::LUDTS;
dataLen = ludtLength; dataLen = ludtLength;
} else { // Segmentation is needed!!! } else { // Segmentation is needed!!!
@ -3317,7 +3326,7 @@ int SS7SCCP::segmentMessage(SS7MsgSCCP* origMsg, const SS7Label& label, bool loc
origMsg->updateType(msgType); origMsg->updateType(msgType);
origMsg->params().clearParam(YSTRING("Segmentation"),'.'); origMsg->params().clearParam(YSTRING("Segmentation"),'.');
// Send the message if it fits in a single message // Send the message if it fits in a single message
if (data->length() < dataLen) { if (data->length() <= dataLen) {
Lock lock(this); Lock lock(this);
ajustMessageParams(origMsg->params(),origMsg->type()); ajustMessageParams(origMsg->params(),origMsg->type());
SS7MSU* msu = buildMSU(origMsg,label,false); SS7MSU* msu = buildMSU(origMsg,label,false);
@ -3339,12 +3348,13 @@ int SS7SCCP::segmentMessage(SS7MsgSCCP* origMsg, const SS7Label& label, bool loc
return sls; return sls;
} }
// Verify if we should bother to segment the message // Verify if we should bother to segment the message
if (data->length() > 16 * (dataLen - 1)) { if ((data->length() > 16 * (dataLen - 1)) && !isSCLCSMessage(msgType)) {
Debug(DebugNote, Debug(DebugNote,
"Unable to segment SCCP message! Data length (%d) excedes max data allowed (%d)", "Unable to segment SCCP message! Data length (%d) excedes max data allowed (%d)",
data->length(),(16 * (dataLen - 1))); data->length(),(16 * (dataLen - 1)));
return -1; return -1;
} }
// Start segmentation process // Start segmentation process
lock(); lock();
ObjList* listSegments = getDataSegments(data->length(),dataLen); ObjList* listSegments = getDataSegments(data->length(),dataLen);