Cannot send SMS more then 140 via HUAWEI USB stick modem

天涯浪子 提交于 2019-12-11 18:56:19

问题


I use HUAWEI USB stick modem and code below to send SMS successfully but under 140 of length (see the code pls -- double lenMes = textsms.Length / 2;).

But nowdays I see the really big SMS messages.

So I am wondering what's wrong with AT commnds or may me hardware is old so I cannot send big SMS.

Please any clue?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;


namespace sendSMSPDU
{
    class Program
    {
        static SerialPort port;

        static void Main(string[] args)
        {
            port = new SerialPort();

            Console.WriteLine("Sending SMS");

            OpenPort();
            bool result;

            result = sendSMS("Some text that less 140 is gonna sending OK", " +75434355544");

            if (result == true)
            {
                Console.WriteLine("OK");
            }
            else
            {
                Console.WriteLine("ERROR");
            }
            Console.ReadLine();

            port.Close();
        }



        private static bool sendSMS(string textsms, string telnumber)
        {
            if (!port.IsOpen) return false;

            try
            {
                System.Threading.Thread.Sleep(500);
                port.WriteLine("AT\r\n");  
                System.Threading.Thread.Sleep(500);

                port.Write("AT+CMGF=0\r\n"); 
                System.Threading.Thread.Sleep(500);
            }
            catch
            {
                return false;
            }

            try
            {
                telnumber = telnumber.Replace("-", "").Replace(" ", "").Replace("+", "");


                telnumber = "01" + "00" + telnumber.Length.ToString("X2") + "91" + EncodePhoneNumber(telnumber);

                textsms = StringToUCS2(textsms);

                string leninByte = (textsms.Length / 2).ToString("X2");
                textsms = telnumber + "00" + "08" + leninByte + textsms;


                double lenMes = textsms.Length / 2;

                if (lenMes < 140) // It sends OK
                {
                    port.Write("AT+CMGS=" + (Math.Ceiling(lenMes)).ToString() + "\r\n");
                    System.Threading.Thread.Sleep(500);


                    textsms = "00" + textsms;

                    port.Write(textsms + char.ConvertFromUtf32(26) + "\r\n");
                    System.Threading.Thread.Sleep(500);
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }

            try
            {
                string recievedData;
                recievedData = port.ReadExisting();

                if (recievedData.Contains("ERROR"))
                {
                    return false;
                }

            }
            catch { }

            return true;
        }


        private static void OpenPort()
        {

            port.BaudRate = 9600;  
            port.DataBits = 7;  

            port.StopBits = StopBits.One;          
            port.Parity = Parity.Odd;  

            port.ReadTimeout = 500;  
            port.WriteTimeout = 500;  

            //port.Handshake = Handshake.RequestToSend;
            //port.DtrEnable = true;
            //port.RtsEnable = true;
            //port.NewLine = Environment.NewLine;

            port.Encoding = Encoding.GetEncoding("windows-1252");

            port.PortName = "COM7";


            if (port.IsOpen)
                port.Close();
            try
            {
                port.Open();
            }
            catch { }

        }




        public static string EncodePhoneNumber(string PhoneNumber)
        {
            string result = "";
            if ((PhoneNumber.Length % 2) > 0) PhoneNumber += "F";

            int i = 0;
            while (i < PhoneNumber.Length)
            {
                result += PhoneNumber[i + 1].ToString() + PhoneNumber[i].ToString();
                i += 2;
            }
            return result.Trim();
        }



        public static string StringToUCS2(string str)
        {
            UnicodeEncoding ue = new UnicodeEncoding();
            byte[] ucs2 = ue.GetBytes(str);

            int i = 0;
            while (i < ucs2.Length)
            {
                byte b = ucs2[i + 1];
                ucs2[i + 1] = ucs2[i];
                ucs2[i] = b;
                i += 2;
            }
            return BitConverter.ToString(ucs2).Replace("-", "");
        }


    }
}

回答1:


Single SMS message is limited to 160 (or 152 in PDU mode) symbols in GSM-7 encoding. More than that, if there is any symbol not listed here you need to use UCS-2 encoding and your messages now limit to 67 symbols. If you need to send longer messages, you are welcome to the "bright and shiny world" of SMS PDU mode.

So sending a long sms is as easy as:

  1. Split it to parts of 67 (or 152) symbols;
  2. Convert this parts to UCS-2 or GSM-7 encoding;
  3. Transform them to PDU messages;
  4. Send them sequentially with use of additional AT-command (AT+CMGF=0)

Edit

The one who designed a PDU format is a true evil person. It is really mind breaking thing and I don't want to write a convertion code, sorry. But, I can point you with this stub:

protected void SendMessage(string phoneNumber, string message)
{
    const char CR = '\r'; // "Carage Return"
    const char CtrlZ = (char)26; // Ctrl+Z character

    var header = GeneratePDUHeader(phoneNumber);
    foreach (var messagePart in SplitSMSMessage(message))
    {
        SendToCOM("AT+CMGF=0" + CR);
        SendToCOM("AT+CMGS=42" + CR);
        SendToCOM($"{header}{messagePart}" + CtrlZ);
    }
}

// should return something like "0041000B910000000000F000088C"
protected string GeneratePDUHeader(string phoneNumber) { }

// split long message to parts
protected IEnumerable<string> SplitSMSMessage(string message)
{
    var useUCSEncoding = IsUCSEncodingNeeded(message);
    var partLength = useUCSEncoding ? 67 : 152;

    var messageParts = Enumerable.Range(0, message.Length / partLength)
        .Select(i => message.Substring(i * partLength, partLength))
        .ToArray();

    var referenceNumber = $"{GenerateReferenceNumber():X2}"; // convert to HEX, i.e. "01"
    var totalMessagesCount = $"{messageParts.Length:X2}";    // convert to HEX, i.e. "01"
    var udhBase = $"050003{referenceNumber}{totalMessagesCount}";

    var messageNumber = (char)0;
    foreach (var messagePart in messageParts)
    {
        var udh = $"{udhBase}{++messageNumber}";
        var messagePartText = useUCSEncoding ? StringToUCS(messagePart) : StringToGSM7(messagePart);
        yield return $"{udh}{messagePartText}";
    }
}

private void SendToCOM(string message) { } // writes message to COM port
private bool IsUCSEncodingNeeded(string message) { } // determine if UCS-2 convert is required
private char GenerateReferenceNumber() { } // random number 0-255
private string StringToUCS(string message) { } // convert string to UCS encoding
private string StringToGSM7(string message) { } // convert string to GSM7 encoding (don't forget about padding!)

You may also find this links are useful:

  • https://en.wikipedia.org/wiki/Concatenated_SMS
  • https://www.developershome.com/sms/cmgsCommand4.asp



回答2:


The best answer to my question is here

How to concat long SMS in GSMComm Library?

https://github.com/welly87/GSMComm

https://www.nuget.org/packages/GSMComm/

It work fine with my HUAWEI GSM modem! WOW!



来源:https://stackoverflow.com/questions/51053983/cannot-send-sms-more-then-140-via-huawei-usb-stick-modem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!