Exemplo n.º 1
0
        /// <summary>
        /// Apply segmentation over a message possibly splitting it on multiple SMPP PDUs.
        /// </summary>
        /// <remarks>
        /// Method may return the passed pdu (modified as needed) as result in case no splitting is required.
        /// </remarks>
        /// <param name="pdu">The base pdu to use.</param>
        /// <param name="method">The segmentation & reasembly method tu use when splitting the message.</param>
        /// <param name="correlationId">The correlation id to set to each message part.</param>
        /// <returns>The list of sequence numbers of PDUs sent</returns>
        public static IEnumerable<SmppSubmitSm> SplitLongMessage(SmppSubmitSm pdu, SmppSarMethod method, byte correlationId)
        {
            if (pdu == null) throw new ArgumentNullException("pdu");

            var result = new List<SmppSubmitSm>();
            var data = pdu.MessagePayload != null ? pdu.MessagePayload : pdu.ShortMessage;

            if (data != null && !(data is string || data is byte[]))
                throw new ArgumentException("Short Message must be a string or byte array.");

            var bytes = data is string ? PduUtil.GetEncodedText(pdu.DataCoding, data as string) : data as byte[];
            var maxSegmentLen = GetMaxSegmentLength(pdu.DataCoding, bytes.Length);

            // Remove/Reset data from PDU..
            pdu.ShortMessage = pdu.MessagePayload = null;
            // Remove sequenceNumber.
            pdu.SequenceNumber = 0;
            // Remove UDH header (if set).
            pdu.EsmClass &= ((byte)~NetworkFeatures.UDHI);
            // Remove SMPP segmentation properties..
            pdu.MoreMessagesToSend = null;
            pdu.NumberOfMessages = null;
            pdu.SarTotalSegments = null;
            pdu.SarMsgRefNumber = null;

            // Sending as payload means avoiding all the data splitting logic.. (which is great ;))
            if (method == SmppSarMethod.SendAsPayload)
            {
                pdu.MessagePayload = data;
                return new[] { pdu };
            }

            // Else.. let's do segmentation and the other crappy stuff..
            var udhref = method == SmppSarMethod.UserDataHeader ? new Nullable<byte>(correlationId) : null;
            var segments = SplitMessage(bytes, maxSegmentLen, udhref);
            var totalSegments = segments.Count();
            var segno = 0;

            // If just one segment, send it w/o SAR parameters..
            if (totalSegments < 2)
            {
                pdu.ShortMessage = data;
                return new[] { pdu };
            }

            // Ok, se we need segmentation, let's go ahead an use input PDU as template.
            var template = pdu.GetEncodedPdu();
            // Well save results here..
            var results = new List<SmppSubmitSm>();

            foreach (var segment in segments)
            {
                var packet = new SmppSubmitSm(template);

                segno++; // Increase sequence number.
                packet.SequenceNumber = 0; // Remove sequenceNumber.
                packet.ShortMessage = segment; // Set current segment bytes as short message..

                switch (method)
                {
                    case SmppSarMethod.UserDataHeader:
                        packet.EsmClass |= (byte)NetworkFeatures.UDHI; // Set UDH flag..
                        break;
                    case SmppSarMethod.UseSmppSegmentation:
                        packet.EsmClass &= ((byte)~NetworkFeatures.UDHI); // Remove UDH header (if set).
                        // Fill-in SMPP segmentation fields..
                        packet.MoreMessagesToSend = segno != totalSegments;
                        packet.NumberOfMessages = (byte)totalSegments;
                        packet.SarTotalSegments = (byte)totalSegments;
                        packet.SarMsgRefNumber = correlationId;
                        packet.SarSegmentSeqnum = (byte)segno;
                        break;
                }

                result.Add(packet);
            }

            return result;
        }