📄 sgip.cs
字号:
using System;
using System.Collections;
using System.Text;
using System.Runtime.CompilerServices;
using System.Net;
namespace UNSMSGW12API
{
/// <summary>
/// 专用SGIP协议中定义的消息由消息头和消息体组成
/// </summary>
public class Command
{
#region 命令ID
public const uint SGIP_BIND = 0x1;
public const uint SGIP_BIND_RESP = 0x80000001;
public const uint SGIP_UNBIND = 0x2;
public const uint SGIP_UNBIND_RESP = 0x80000002;
public const uint SGIP_SUBMIT = 0x3;
public const uint SGIP_SUBMIT_RESP = 0x80000003;
public const uint SGIP_DELIVER = 0x4;
public const uint SGIP_DELIVER_RESP = 0x80000004;
public const uint SGIP_REPORT = 0x5;
public const uint SGIP_REPORT_RESP = 0x80000005;
public const uint SGIP_ADDSP = 0x6;
public const uint SGIP_ADDSP_RESP = 0x80000006;
public const uint SGIP_MODIFYSP = 0x7;
public const uint SGIP_MODIFYSP_RESP = 0x80000007;
public const uint SGIP_DELETESP = 0x8;
public const uint SGIP_DELETESP_RESP = 0x80000008;
public const uint SGIP_QUERYROUTE = 0x9;
public const uint SGIP_QUERYROUTE_RESP = 0x80000009;
public const uint SGIP_ADDTELESEG = 0xa;
public const uint SGIP_ADDTELESEG_RESP = 0x8000000a;
public const uint SGIP_MODIFYTELESEG = 0xb;
public const uint SGIP_MODIFYTELESEG_RESP = 0x8000000b;
public const uint SGIP_DELETETELESEG = 0xc;
public const uint SGIP_DELETETELESEG_RESP = 0x8000000c;
public const uint SGIP_ADDSMG = 0xd;
public const uint SGIP_ADDSMG_RESP = 0x8000000d;
public const uint SGIP_MODIFYSMG = 0xe;
public const uint SGIP_MODIFYSMG_RESP = 0x0000000e;
public const uint SGIP_DELETESMG = 0xf;
public const uint SGIP_DELETESMG_RESP = 0x8000000f;
public const uint SGIP_CHECKUSER = 0x10;
public const uint SGIP_CHECKUSER_RESP = 0x80000010;
public const uint SGIP_USERRPT = 0x11;
public const uint SGIP_USERRPT_RESP = 0x80000011;
public const uint SGIP_TRACE = 0x1000;
public const uint SGIP_TRACE_RESP = 0x80001000;
//下面两个命令是自定义的
public const uint SGIP_KEEPALIVE = 0x10000001;
public const uint SGIP_KEEPALIVE_RESP = 0x10000010;
#endregion
#region 错误代码
/// <summary>
/// 无错误,命令正确接收
/// </summary>
public const byte ERR_Success = 0;
public const byte ERR_InvalidLogin = 1; //非法登录,如登录名、口令出错、登录名与口令不符等。
public const byte ERR_RepeatLogin = 2; //重复登录,如在同一TCP/IP连接中连续两次以上请求登录。
public const byte ERR_TooMuchLink = 3; //连接过多,指单个节点要求同时建立的连接数过多。
public const byte ERR_LoginTypeError = 4; //登录类型错,指bind命令中的logintype字段出错。
public const byte ERR_ParFormatError = 5; //参数格式错,指命令中参数值与参数类型不符或与协议规定的范围不符。
public const byte ERR_InvalidPhone = 6; //非法手机号码,协议中所有手机号码字段出现非86130号码或手机号码前未加"86"时都应报错。
public const byte ERR_MessageIDError = 7; //消息ID错
public const byte ERR_MessageLenError = 8; //信息长度错
public const byte ERR_InvalidSerialNo = 9; //非法序列号,包括序列号重复、序列号格式错误等
public const byte ERR_InvalidOper = 10; //非法操作GNS
public const byte ERR_ComputerBusy = 11; //节点忙,指本节点存储队列满或其他原因,暂时不能提供服务的情况
public const byte ERR_DestCantReach = 21; //目的地址不可达,指路由表存在路由且消息路由正确但被路由的节点暂时不能提供服务的情况
public const byte ERR_RoutError = 22; //路由错,指路由表存在路由但消息路由出错的情况,如转错SMG等
public const byte ERR_RoutNotExist = 23; //路由不存在,指消息路由的节点在路由表中不存在
public const byte ERR_FeeNoInvalid = 24; //计费号码无效,鉴权不成功时反馈的错误信息
public const byte ERR_UserCantCommu = 25; //用户不能通信(如不在服务区、未开机等情况)
public const byte ERR_MobileMemoLack = 26; //手机内存不足
public const byte ERR_MobileNosupportSMG = 27; //手机不支持短消息
public const byte ERR_MobileReceiError = 28; //手机接收短消息出现错误
public const byte ERR_NoThisUser = 29; //不知道的用户
public const byte ERR_NoThisFunction = 30; //不提供此功能
public const byte ERR_InvalidDevice = 31; //非法设备
public const byte ERR_SysError = 32; //系统失败
public const byte ERR_SMGQueFull = 33; //短信中心队列满
#endregion
#region 计费类别,参考SGIP1.2协议5.3节
public const byte FEETYPE_0=0; //“短消息类型”为“发送”,对“计费用户号码”不计信息费,此类话单仅用于核减SP对称的信道费
public const byte FEETYPE_1=1; //对“计费用户号码”免费
public const byte FEETYPE_2=2; //对“计费用户号码”按条计信息费
public const byte FEETYPE_3=3; //对“计费用户号码”按包月收取信息费
public const byte FEETYPE_4=4; //对“计费用户号码”的收费是由SP实现
#endregion
private Head _head = null;
private Body _body = null;
public Head Head
{
get { return _head; }
set { _head = value; }
}
public Body Body
{
get { return _body; }
set { _body = value; }
}
public int GetLength()
{
return _head.GetLength() + _body.GetLength();
}
public byte[] GetBytes()
{
byte[] result = new byte[this.GetLength()];
Buffer.BlockCopy(_head.GetBytes(), 0, result, 0, _head.GetLength());
Buffer.BlockCopy(_body.GetBytes(), 0, result, _head.GetLength(), _body.GetLength());
return result;
}
internal void ReadFromBytes(byte[] buffer, int startIndex)
{
_head.ReadFromBytes(buffer, startIndex);
_body.ReadFromBytes(buffer, startIndex + _head.GetLength());
}
/// <summary>
/// 用户须调用 ToCommand或CreateCommand方法创建该类的对象
/// </summary>
internal Command()
{
}
public static Command ToCommand(byte[] buffer, int startIndex)
{
Command cmd = new Command();
cmd.Head = Head.ToHead(buffer, startIndex);
switch (cmd.Head.CommandID)
{
case Command.SGIP_BIND:
cmd.Body = new Bind();
break;
case Command.SGIP_BIND_RESP:
cmd.Body = new Bind_Resp();
break;
case Command.SGIP_UNBIND:
cmd.Body = new Unbind();
break;
case Command.SGIP_UNBIND_RESP:
cmd.Body = new Unbind_Resp();
break;
case Command.SGIP_SUBMIT:
cmd.Body = new Submit();
break;
case Command.SGIP_SUBMIT_RESP:
cmd.Body = new Submit_Resp();
break;
case Command.SGIP_DELIVER:
cmd.Body = new Deliver();
break;
case Command.SGIP_DELIVER_RESP:
cmd.Body = new Deliver_Resp();
break;
case Command.SGIP_REPORT:
cmd.Body = new Report();
break;
case Command.SGIP_REPORT_RESP:
cmd.Body = new Report_Resp();
break;
case Command.SGIP_TRACE:
cmd.Body = new Trace();
break;
case Command.SGIP_TRACE_RESP:
cmd.Body = new Trace_Resp();
break;
case Command.SGIP_USERRPT:
cmd.Body = new UserRpt();
break;
case Command.SGIP_USERRPT_RESP:
cmd.Body = new UserRpt_Resp();
break;
case Command.SGIP_KEEPALIVE:
cmd.Body = new KeepAlive();
break;
case Command.SGIP_KEEPALIVE_RESP:
cmd.Body = new KeepAlive_Resp();
break;
default:
throw new InvalidCastException("未知命令!无法解析.");
} // end of switch
cmd.Body.ReadFromBytes(buffer, startIndex + cmd.Head.GetLength());
return cmd;
}
/// <summary>
/// 创建一个命令,多在发送命令时用
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
public static Command CreateCommand(Body body)
{
return Command.CreateCommand(SequenceNumber.CreateSequenceNumber(), body);
}
/// <summary>
/// 创建一个命令(多在应答时用)
/// </summary>
/// <param name="sequenceNumber"></param>
/// <param name="body"></param>
/// <returns></returns>
public static Command CreateCommand(SequenceNumber sequenceNumber, Body body)
{
Command cmd = new Command();
cmd.Body = body;
cmd.Head = new Head();
cmd.Head.CommandID = body.GetCommandID();
cmd.Head.MessageLength = (uint)cmd.GetLength();
cmd.Head.SequenceNumber.Assign(sequenceNumber);
return cmd;
}
}
/// <summary>
/// 消息头的定义,20字节
/// </summary>
public class Head
{
private uint _messageLength; // 4
private uint _commandID; // 4
private SequenceNumber _sequenceNumber = new SequenceNumber(); //12, 注意:尚未进行正确的赋值
public uint MessageLength
{
get
{
return (uint)IPAddress.NetworkToHostOrder((int)_messageLength);
}
set
{
_messageLength = (uint)IPAddress.HostToNetworkOrder((int)value);
}
}
public uint CommandID
{
get
{
return (uint)IPAddress.NetworkToHostOrder((int)_commandID);
}
set
{
_commandID = (uint)IPAddress.HostToNetworkOrder((int)value);
}
}
public SequenceNumber SequenceNumber
{
get { return _sequenceNumber; }
set { _sequenceNumber = value; }
}
public Head()
{
}
/// <summary>
/// 返回byte[], 用于socket发送
/// </summary>
/// <returns></returns>
public byte[] GetBytes()
{
byte[] result = new byte[this.GetLength()];
int nIndex = 0;
BitConverter.GetBytes(_messageLength).CopyTo(result, nIndex);
nIndex += 4;
BitConverter.GetBytes(_commandID).CopyTo(result, nIndex);
nIndex += 4;
_sequenceNumber.GetBytes().CopyTo(result, nIndex);
return result;
}
/// <summary>
/// 从byte[]中读取数据
/// </summary>
/// <param name="buffer"></param>
/// <param name="startIndex"></param>
internal void ReadFromBytes(byte[] buffer, int startIndex)
{
_messageLength = BitConverter.ToUInt32(buffer, startIndex);
_commandID = BitConverter.ToUInt32(buffer, startIndex + 4);
_sequenceNumber.ReadFromBytes(buffer, startIndex + 8);
}
public static Head ToHead(byte[] buffer, int startIndex)
{
Head head = new Head();
head.ReadFromBytes(buffer, startIndex);
return head;
}
/// <summary>
/// 返回head这一结构所占用的字节数
/// </summary>
/// <returns></returns>
public int GetLength()
{
return 20;
}
};
public class Body
{
public virtual uint GetCommandID()
{
return 0;
}
public virtual int GetLength()
{
return 0;
}
public virtual byte[] GetBytes()
{
return new byte[0];
}
internal virtual void ReadFromBytes(byte[] buffer, int startIndex)
{
}
}
public class ResponseBody : Body
{
private byte _result;
private byte[] _reserved = new byte[8]{0,0,0,0,0,0,0,0};
/// <summary>
/// Bind执行命令是否成功。0:执行成功, 其它:错误码
/// </summary>
public byte Result
{
get
{
return _result;
}
set
{
_result = value;
}
}
/// <summary>
/// 保留,最多8个字节
/// </summary>
public byte[] Reserved
{
get { return _reserved; }
set
{
apiHelper.CheckMaxBytes(value, 8);
_reserved = value;
}
}
public override int GetLength()
{
return 9;
}
public override byte[] GetBytes()
{
byte[] buffer = new byte[this.GetLength()];
buffer[0] = _result;
_reserved.CopyTo(buffer, 1);
return buffer;
}
internal override void ReadFromBytes(byte[] buffer, int startIndex)
{
_result = buffer[startIndex];
Buffer.BlockCopy(buffer, 1, _reserved, 0, 8);
}
}
/// <summary>
/// 序列号, 参见: 3.4序列号的定义, 12字节
/// </summary>
public class SequenceNumber
{
//保存的值将是网络字节顺序的值
private uint _part1;
private uint _part2;
private uint _part3;
private static uint _Sequence = 0; //用于第3部分,序号计数
public uint Part1
{
get
{
return (uint)IPAddress.NetworkToHostOrder((int)_part1);
}
set
{
_part1 = (uint)IPAddress.HostToNetworkOrder((int)value);
}
}
public uint Part2
{
get
{
return (uint)IPAddress.NetworkToHostOrder((int)_part2);
}
set
{
_part2 = (uint)IPAddress.HostToNetworkOrder((int)value);
}
}
public uint Part3
{
get
{
return (uint)IPAddress.NetworkToHostOrder((int)_part3);
}
set
{
_part3 = (uint)IPAddress.HostToNetworkOrder((int)value);
}
}
/// <summary>
/// 将另一个序列号赋值给自已, 这在消息应答时用
/// </summary>
/// <param name="r"></param>
public void Assign(SequenceNumber r)
{
this._part1 = r._part1;
this._part2 = r._part2;
this._part3 = r._part3;
}
/// <summary>
/// 返回所占用的字节数
/// </summary>
/// <returns></returns>
public int GetLength()
{
return 12;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -