📄 smsbase.cs
字号:
using System;
using System.Text;
using System.Collections.Generic;
namespace SMSPDULib
{
public enum SMSDirection
{
Received = 0,
Submited = 1
}
public enum SMSType
{
SMS = 0,
StatusReport = 1
}
public enum ValidityPeriodFormat
{
FieldNotPresent = 0,
Relative = 0x10,
Enhanced = 0x08,
Absolute = 0x18
}
public abstract class SMSBase
{
#region Public Statics (Pops, Peeks, Gets)
public static byte[] GetInvertBytes(string source)
{
byte[] bytes = GetBytes(source);
Array.Reverse(bytes);
return bytes;
}
public static byte[] GetBytes(string source)
{
return GetBytes(source, 16);
}
public static byte[] GetBytes(string source, int fromBase)
{
List<byte> bytes = new List<byte>();
for (int i = 0; i < source.Length / 2; i++)
bytes.Add(Convert.ToByte(source.Substring(i * 2, 2), fromBase));
return bytes.ToArray();
}
public static string Decode7bit(string source, int length)
{
byte[] bytes = GetInvertBytes(source);
string binary = string.Empty;
foreach (byte b in bytes)
binary += Convert.ToString(b, 2).PadLeft(8, '0');
binary = binary.PadRight(length * 7, '0');
string result = string.Empty;
for (int i = 1; i <= length; i++)
result += (char) Convert.ToByte(binary.Substring(binary.Length - i * 7, 7), 2);
return result.Replace('\x0', '\x40');
}
public static string Decode8bit(string source, int length)
{
byte[] bytes = GetBytes(source.Substring(0, length * 2));
//or ASCII?
return Encoding.UTF8.GetString(bytes);
}
public static string DecodeUCS2(string source, int length)
{
byte[] bytes = GetBytes(source.Substring(0, length * 2));
return Encoding.BigEndianUnicode.GetString(bytes);
}
public static byte[] EncodeUCS2(string s)
{
return Encoding.BigEndianUnicode.GetBytes(s);
}
public static string ReverseBits(string source)
{
return ReverseBits(source, source.Length);
}
public static string ReverseBits(string source, int length)
{
string result = string.Empty;
for (int i = 0; i < length; i++)
result = result.Insert(i % 2 == 0 ? i : i - 1, source[i].ToString());
return result;
}
public static byte PeekByte(string source)
{
return PeekByte(source, 0);
}
public static byte PeekByte(string source, int byteIndex)
{
return Convert.ToByte(source.Substring(byteIndex * 2, 2), 16);
}
public static byte PopByte(ref string source)
{
byte b = Convert.ToByte(source.Substring(0, 2), 16);
source = source.Substring(2);
return b;
}
public static byte[] PopBytes(ref string source, int length)
{
string bytes = source.Substring(0, length * 2);
source = source.Substring(length * 2);
return GetBytes(bytes);
}
public static DateTime PopDate(ref string source)
{
byte[] bytes = GetBytes(ReverseBits(source.Substring(0, 12)), 10);
source = source.Substring(14);
return new DateTime(2000 + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]);
}
public static string PopPhoneNumber(ref string source)
{
int numberLength = PopByte(ref source);
if ((numberLength = numberLength + 2) == 2)
return string.Empty;
return PopAddress(ref source, numberLength + (numberLength % 2));
}
public static string PopServiceCenterAddress(ref string source)
{
int addressLength = PopByte(ref source);
if ((addressLength = addressLength * 2) == 0)
return string.Empty;
return PopAddress(ref source, addressLength);
}
public static string PopAddress(ref string source, int length)
{
string address = source.Substring(0, length);
source = source.Substring(address.Length);
byte addressType = PopByte(ref address);
address = ReverseBits(address).Trim('F');
if (0x09 == addressType >> 4)
address = "+" + address;
return address;
}
public static SMSType GetSMSType(string source)
{
byte scaLength = PeekByte(source);
byte pduType = PeekByte(source, scaLength + 1);
byte smsType = (byte) ((pduType & 3) >> 1);
if (!Enum.IsDefined(typeof(SMSType), (int) smsType))
throw new UnknownSMSTypeException(pduType);
return (SMSType) smsType;
}
public static void Fetch(SMSBase sms, ref string source)
{
sms._serviceCenterNumber = PopServiceCenterAddress(ref source);
sms._pduType = PopByte(ref source);
System.Collections.BitArray bits = new System.Collections.BitArray(new byte[] { sms._pduType });
sms.ReplyPathExists = bits[7];
sms.UserDataStartsWithHeader = bits[6];
sms.StatusReportIndication = bits[5];
sms.ValidityPeriodFormat = (ValidityPeriodFormat) (sms._pduType & 0x18);
sms.Direction = (SMSDirection) (sms._pduType & 1);
}
#endregion
#region Public Statics (Push)
public static string EncodePhoneNumber(string phoneNumber)
{
bool isInternational = phoneNumber.StartsWith("+");
if (isInternational)
phoneNumber = phoneNumber.Remove(0, 1);
int header = (phoneNumber.Length << 8) + 0x81 | (isInternational ? 0x10 : 0x20);
if (phoneNumber.Length % 2 == 1)
phoneNumber = phoneNumber.PadRight(phoneNumber.Length + 1, 'F');
phoneNumber = ReverseBits(phoneNumber);
return Convert.ToString(header, 16).PadLeft(4, '0') + phoneNumber;
}
#endregion
#region Publics
public virtual void ComposePDUType()
{
_pduType = (byte) Direction;
_pduType = (byte) (_pduType | (int) ValidityPeriodFormat);
if (StatusReportIndication)
_pduType = (byte) (_pduType | 0x20);
}
#endregion
#region Members
//protected SMSType _type;
protected byte _pduType;
protected string _serviceCenterNumber;
#region PDU type (first octet) data
//Reply path. Parameter indicating that reply path exists.
protected bool _replyPathExists;
//User data header indicator. This bit is set to 1 if the User Data field starts with a header. (EMS?)
protected bool _userDataStartsWithHeader;
//Status report indication. This bit is set to 1 if a status report is going to be returned to the SME.
protected bool _statusReportIndication;
//Validity Period Format
protected ValidityPeriodFormat _validityPeriodFormat = ValidityPeriodFormat.FieldNotPresent;
//Message type indication
//First bit
protected SMSDirection _direction;
#endregion
#endregion
#region Proreties
public string ServiceCenterNumber
{
get { return _serviceCenterNumber; }
set { _serviceCenterNumber = value; }
}
public bool ReplyPathExists
{
get { return _replyPathExists; }
set { _replyPathExists = value; }
}
public bool UserDataStartsWithHeader
{
get { return _userDataStartsWithHeader; }
set { _userDataStartsWithHeader = value; }
}
public bool StatusReportIndication
{
get { return _statusReportIndication; }
set { _statusReportIndication = value; }
}
public ValidityPeriodFormat ValidityPeriodFormat
{
get { return _validityPeriodFormat; }
set { _validityPeriodFormat = value; }
}
public SMSDirection Direction
{
get { return _direction; }
set { _direction = value; }
}
public abstract SMSType Type { get; }
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -