alexandr-mironov / php8-smpp

SMPP Client (v 3.4) on PHP8
7 stars 8 forks source link

Unicode SMS segmentation issue, for 3 parts sending as 4 part #16

Closed dfangys closed 6 months ago

dfangys commented 10 months ago

Hello, I believe I've resolved an issue in your repository related to the splitting of Unicode SMS messages into 3 parts in the SMPP protocol. Please review the following changes I made:

1- Account for the User Data Header (UDH) when calculating message splits. The UDH for concatenated messages is typically 6 octets (or bytes) in length. 2- Ensure that when calculating the length of a UCS2 encoded message, we account for the fact that each character is represented by 2 octets. Here's the modified code:

in /src/Client.php at sendSMS function

` public function sendSMS( Address $from, Address $to, string $message, array $tags = null, int $dataCoding = Smpp::DATA_CODING_DEFAULT, int $priority = 0x00, $scheduleDeliveryTime = null, $validityPeriod = null ): bool|string { $messageLength = strlen($message);

if ($messageLength > 160 && !in_array($dataCoding, [Smpp::DATA_CODING_UCS2, Smpp::DATA_CODING_DEFAULT])) {
    return false;
}

$udhLength = 6; // Typically 6 octets for concatenated SMS

switch ($dataCoding) {
         case Smpp::DATA_CODING_UCS2:
        // in octets, 70 UCS-2 chars
        $singleSmsOctetLimit = 140;  // 70 characters * 2 bytes per character

        // Adjusting for UDH and ensuring we don't split a UCS character
        // Also, considering the UDH length (6 octets for concatenated messages)
        $udhLength = ($messageLength > $singleSmsOctetLimit) ? 6 : 0;  // UDH only for multipart
        $csmsSplit = $singleSmsOctetLimit - $udhLength;  // Reduce available size by UDH length

        $message = mb_convert_encoding($message, 'UCS-2BE', 'auto');  // Ensure correct encoding
        $messageLength = mb_strlen($message, '8bit');  // Count bytes, not characters

        // Calculate the number of messages
        $numMessages = ceil($messageLength / $csmsSplit);  // Total parts
        if ($numMessages > 1) {
            // If multipart, adjust split to ensure it's even (UCS-2 characters are 2 bytes)
            $csmsSplit -= ($csmsSplit % 2);
        }
        break;
    case Smpp::DATA_CODING_DEFAULT:
        // we send data in octets, but GSM 03.38 will be packed in septets (7-bit) by SMSC.
        $singleSmsOctetLimit = 160;
        // Adjust for UDH and decide based on the csms method
        $csmsSplit = (self::$csmsMethod == self::CSMS_8BIT_UDH) ? (153 - $udhLength) : (152 - $udhLength);
        break;
    default:
        $singleSmsOctetLimit = 254; // From SMPP standard
        break;
}
`
alexandr-mironov commented 10 months ago

Hello, thanks for your participation! Can you create a pull request with changes? so i can make review and if it has no issues to merge in master

dfangys commented 6 months ago

Hello, thanks for your participation! Can you create a pull request with changes? so i can make review and if it has no issues to merge in master

pull request has been created