как найти способ декодирования для декодирования результата команды USSD в С #?

Я работаю над своим GSM-модемом (Huawei E171), чтобы отправлять USSD-команды. для этого я сначала использую эти команды:

AT+CMGF=1
AT+CSCS=?  ----> result is "IRA" this is my modem default

после этого я отправил эти команды, и я получил эти результаты, и все работает нормально.

// * 141 * 1 # -----> для проверки баланса

+CUSD: 
   0,"457A591C96EB40B41A8D0692A6C36C17688A2E9FCB667AD87D4EEB4130103D
      0C8281E4753D0B1926E7CB2018881E06C140F2BADE5583819A4250D24D2FC
      BDD653A485AD787DD65504C068381A8EF76D80D2287E53A55AD5653D554
      31956D04",15

// * 100 # ----> эта команда дает мне несколько вариантов зарядки моего мобильного телефона

+CUSD: 
    1,"06280627062C06470020062706CC06310627064606330644000A0030002E062E0
       63106CC062F00200634062706310698000A0031002E067E062706330627063106A
       F0627062F000A0032002E0622067E000A0033002E06450644062A000A003
       4002E06330627064506270646000A0035002E067E0627063106330
       6CC06270646000A002300200028006E0065007800740029000A",72

Я нашел несколько кодов для декодирования этого результата:

для расшифровки результата проверки баланса я использовал:

        string result141="457A591C96EB40B41A8D0692A6C36C17688A......."
        byte[] packedBytes = ConvertHexToBytes(result141);
        byte[] unpackedBytes = UnpackBytes(packedBytes);

        //gahi in kar mikone gahi balkaee nafahmidam chera
        string o = Encoding.Default.GetString(unpackedBytes);

коды моей функции:

   public static byte[] ConvertHexToBytes(string hexString)
    {
           if (hexString.Length % 2 != 0)
               return null;

          int len = hexString.Length / 2;
          byte[] array = new byte[len];

        for (int i = 0; i < array.Length; i++)
        {
            string tmp = hexString.Substring(i * 2, 2);
            array[i] = 
            byte.Parse(tmp, System.Globalization.NumberStyles.HexNumber);
        }

        return array;
    }


   public static byte[] UnpackBytes(byte[] packedBytes)
    {
        byte[] shiftedBytes = new byte[(packedBytes.Length * 8) / 7];

        int shiftOffset = 0;
        int shiftIndex = 0;

        // Shift the packed bytes to the left according 
        //to the offset (position of the byte)
        foreach (byte b in packedBytes)
        {
            if (shiftOffset == 7)
            {
                shiftedBytes[shiftIndex] = 0;
                shiftOffset = 0;
                shiftIndex++;
            }

            shiftedBytes[shiftIndex] = (byte)((b << shiftOffset) & 127);

            shiftOffset++;
            shiftIndex++;
        }

        int moveOffset = 0;
        int moveIndex = 0;
        int unpackIndex = 1;
        byte[] unpackedBytes = new byte[shiftedBytes.Length];

        // 
        if (shiftedBytes.Length > 0)
        {
            unpackedBytes[unpackIndex - 1] = 
            shiftedBytes[unpackIndex - 1];
        }

        // Move the bits to the appropriate byte (unpack the bits)
        foreach (byte b in packedBytes)
        {
            if (unpackIndex != shiftedBytes.Length)
            {
                if (moveOffset == 7)
                {
                    moveOffset = 0;
                    unpackIndex++;
                    unpackedBytes[unpackIndex - 1] = 
                    shiftedBytes[unpackIndex - 1];
                }

                if (unpackIndex != shiftedBytes.Length)
                {
                    // Extract the bits to be moved
                    int extractedBitsByte = (packedBytes[moveIndex] &
                                            _decodeMask[moveOffset]);
                    // Shift the extracted bits to the proper offset
                    extractedBitsByte = 
                               (extractedBitsByte >> (7 - moveOffset));
                    // Move the bits to the appropriate byte 
                    //(unpack the bits)
                    int movedBitsByte = 
                      (extractedBitsByte | shiftedBytes[unpackIndex]);

                    unpackedBytes[unpackIndex] = (byte)movedBitsByte;

                    moveOffset++;
                    unpackIndex++;
                    moveIndex++;
                }
            }
        }

        // Remove the padding if exists
        if (unpackedBytes[unpackedBytes.Length - 1] == 0)
        {
            byte[] finalResultBytes = new byte[unpackedBytes.Length - 1];
            Array.Copy(unpackedBytes, 0, 
                       finalResultBytes, 0, finalResultBytes.Length);
            return finalResultBytes;
        }
        return unpackedBytes;
      }

но для декодирования второго результата я использовал:

string strHex= "06280627062C06470020062706CC06310......";

   strHex = strHex.Replace(" ", "");
          int nNumberChars = strHex.Length / 2;
          byte[] aBytes = new byte[nNumberChars];
          using (var sr = new StringReader(strHex))
          {
            for (int i = 0; i < nNumberChars; i++)
                aBytes[i] = Convert.ToByte(
                            new String(new char[2] { 
                            (char)sr.Read(), (char)sr.Read() }), 16);
        }
   string decodedmessage= Encoding.BigEndianUnicode.
                        GetString(aBytes, 0, aBytes.Length);

обе темы работают в настоящее время, но почему я должен использовать другой способ декодирования для декодирования этих результатов?

откуда я могу найти, какой из этих двух типов декодирования мне следует использовать?


person motevalizadeh    schedule 02.05.2015    source источник


Ответы (1)


Ответы на команды USSD + незапрошенные ответы CUSD имеют следующий формат:

+CUSD: <m>[<str_urc>[<dcs>]]

Где «m» - это тип требуемого действия, «str_urc» - это строка ответа, а «dcs» - это кодировка строки ответа.

Эта цитата взята из руководства Siemens Cinterion MC55i, но в целом применима к другим производителям модемов:

Если dcs указывает, что используется алфавит по умолчанию GSM 03.38, TA преобразует алфавит GSM в текущий набор символов TE в соответствии с правилами Приложения A к GSM 07.05. В противном случае в случае недопустимого или пропущенного dcs преобразование str_urc невозможно.

USSD могут быть отправлены в 7-битном кодированном формате или UC2, поэтому при просмотре двух примеров ответов вы можете увидеть либо DCS 15, либо 72.

Схема кодирования данных сотового вещания GSM 03.38 в целочисленном формате (по умолчанию 15). В случае неверного или пропущенного ЦОД со стороны сети (МТ) не выдаются.

Таким образом, если вы получите DCS 15, то кодировка будет 7-битной. А если 72, то это будет UC2. Таким образом, из этого вы можете легко выбрать либо свою первую процедуру декодирования, либо вторую.

person Matt Aldridge    schedule 02.05.2015
comment
спасибо за хороший ответ, но не могли бы вы сказать мне, пожалуйста, какая связь между 15 и 7-битным кодированием или 75 и UC2, я имею в виду, это формула или что-то для вычисления 75 или 15? или эти числа предопределены? - person motevalizadeh; 02.05.2015
comment
Да, для схемы кодирования есть схема кодирования :) Лучше всего прочитать спецификацию 3GPP 03.38. Найдите схему кодирования данных сотового вещания. Относительно просто, что биты 3 и 2 определяют используемый алфавит. Для 7-битного его Bit3 = 0 Bit2 = 0, а для UC2 его Bit3 = 1 Bit2 = 0. Есть некоторые нюансы по сравнению с кодированием SMS. Детали я не могу вспомнить на 100%. - person Matt Aldridge; 02.05.2015