如何在 C# 中找到解码 USSD 命令结果的解码方法?

how to find decode way to decode a USSD Command's result in c#?

我正在使用我的 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);

这两个主题都是最新的,但为什么我应该使用不同的解码方式来解码这些结果?

从哪里可以找到,我应该使用这两种解码类型中的哪一种?

USSD 命令响应+CUSD 主动响应格式如下:

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

其中 "m" 是所需操作的类型,"str_urc" 是响应字符串,"dcs" 是响应字符串编码。

此引述来自 Siemens Cinterion MC55i 手册,但通常适用于其他调制解调器制造商:

If dcs indicates that GSM 03.38 default alphabet is used TA converts GSM alphabet into current TE character set according to rules of GSM 07.05 Annex A. Otherwise in case of invalid or omitted dcs conversion of str_urc is not possible.

USSD 可以以 7 位编码格式或 UC2 发送,因此在查看您的两个示例响应时,您可以看到 15 或 72 的 DCS。

GSM 03.38 Cell Broadcast Data Coding Scheme in integer format (default 15). In case of an invalid or omitted dcs from the network side (MT) will not be given out.

因此,如果您获得 15 的 DCS,则它是 7 位编码的。如果它是 72 那么它将是 UC2。因此,您可以轻松地 select 您的第一个或第二个解码例程。