?? sgip.cs
字號(hào):
using System;
using System.Collections;
using System.Text;
using System.Runtime.CompilerServices;
using System.Net;
namespace UNSMSGW12API
{
/// <summary>
/// 專(zhuān)用SGIP協(xié)議中定義的消息由消息頭和消息體組成
/// </summary>
public class Command
{
#region 命令I(lǐng)D
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;
//下面兩個(gè)命令是自定義的
public const uint SGIP_KEEPALIVE = 0x10000001;
public const uint SGIP_KEEPALIVE_RESP = 0x10000010;
#endregion
#region 錯(cuò)誤代碼
/// <summary>
/// 無(wú)錯(cuò)誤,命令正確接收
/// </summary>
public const byte ERR_Success = 0;
public const byte ERR_InvalidLogin = 1; //非法登錄,如登錄名、口令出錯(cuò)、登錄名與口令不符等。
public const byte ERR_RepeatLogin = 2; //重復(fù)登錄,如在同一TCP/IP連接中連續(xù)兩次以上請(qǐng)求登錄。
public const byte ERR_TooMuchLink = 3; //連接過(guò)多,指單個(gè)節(jié)點(diǎn)要求同時(shí)建立的連接數(shù)過(guò)多。
public const byte ERR_LoginTypeError = 4; //登錄類(lèi)型錯(cuò),指bind命令中的logintype字段出錯(cuò)。
public const byte ERR_ParFormatError = 5; //參數(shù)格式錯(cuò),指命令中參數(shù)值與參數(shù)類(lèi)型不符或與協(xié)議規(guī)定的范圍不符。
public const byte ERR_InvalidPhone = 6; //非法手機(jī)號(hào)碼,協(xié)議中所有手機(jī)號(hào)碼字段出現(xiàn)非86130號(hào)碼或手機(jī)號(hào)碼前未加"86"時(shí)都應(yīng)報(bào)錯(cuò)。
public const byte ERR_MessageIDError = 7; //消息ID錯(cuò)
public const byte ERR_MessageLenError = 8; //信息長(zhǎng)度錯(cuò)
public const byte ERR_InvalidSerialNo = 9; //非法序列號(hào),包括序列號(hào)重復(fù)、序列號(hào)格式錯(cuò)誤等
public const byte ERR_InvalidOper = 10; //非法操作GNS
public const byte ERR_ComputerBusy = 11; //節(jié)點(diǎn)忙,指本節(jié)點(diǎn)存儲(chǔ)隊(duì)列滿或其他原因,暫時(shí)不能提供服務(wù)的情況
public const byte ERR_DestCantReach = 21; //目的地址不可達(dá),指路由表存在路由且消息路由正確但被路由的節(jié)點(diǎn)暫時(shí)不能提供服務(wù)的情況
public const byte ERR_RoutError = 22; //路由錯(cuò),指路由表存在路由但消息路由出錯(cuò)的情況,如轉(zhuǎn)錯(cuò)SMG等
public const byte ERR_RoutNotExist = 23; //路由不存在,指消息路由的節(jié)點(diǎn)在路由表中不存在
public const byte ERR_FeeNoInvalid = 24; //計(jì)費(fèi)號(hào)碼無(wú)效,鑒權(quán)不成功時(shí)反饋的錯(cuò)誤信息
public const byte ERR_UserCantCommu = 25; //用戶不能通信(如不在服務(wù)區(qū)、未開(kāi)機(jī)等情況)
public const byte ERR_MobileMemoLack = 26; //手機(jī)內(nèi)存不足
public const byte ERR_MobileNosupportSMG = 27; //手機(jī)不支持短消息
public const byte ERR_MobileReceiError = 28; //手機(jī)接收短消息出現(xiàn)錯(cuò)誤
public const byte ERR_NoThisUser = 29; //不知道的用戶
public const byte ERR_NoThisFunction = 30; //不提供此功能
public const byte ERR_InvalidDevice = 31; //非法設(shè)備
public const byte ERR_SysError = 32; //系統(tǒng)失敗
public const byte ERR_SMGQueFull = 33; //短信中心隊(duì)列滿
#endregion
#region 計(jì)費(fèi)類(lèi)別,參考SGIP1.2協(xié)議5.3節(jié)
public const byte FEETYPE_0=0; //“短消息類(lèi)型”為“發(fā)送”,對(duì)“計(jì)費(fèi)用戶號(hào)碼”不計(jì)信息費(fèi),此類(lèi)話單僅用于核減SP對(duì)稱的信道費(fèi)
public const byte FEETYPE_1=1; //對(duì)“計(jì)費(fèi)用戶號(hào)碼”免費(fèi)
public const byte FEETYPE_2=2; //對(duì)“計(jì)費(fèi)用戶號(hào)碼”按條計(jì)信息費(fèi)
public const byte FEETYPE_3=3; //對(duì)“計(jì)費(fèi)用戶號(hào)碼”按包月收取信息費(fèi)
public const byte FEETYPE_4=4; //對(duì)“計(jì)費(fèi)用戶號(hào)碼”的收費(fèi)是由SP實(shí)現(xiàn)
#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>
/// 用戶須調(diào)用 ToCommand或CreateCommand方法創(chuàng)建該類(lèi)的對(duì)象
/// </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("未知命令!無(wú)法解析.");
} // end of switch
cmd.Body.ReadFromBytes(buffer, startIndex + cmd.Head.GetLength());
return cmd;
}
/// <summary>
/// 創(chuàng)建一個(gè)命令,多在發(fā)送命令時(shí)用
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
public static Command CreateCommand(Body body)
{
return Command.CreateCommand(SequenceNumber.CreateSequenceNumber(), body);
}
/// <summary>
/// 創(chuàng)建一個(gè)命令(多在應(yīng)答時(shí)用)
/// </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字節(jié)
/// </summary>
public class Head
{
private uint _messageLength; // 4
private uint _commandID; // 4
private SequenceNumber _sequenceNumber = new SequenceNumber(); //12, 注意:尚未進(jìn)行正確的賦值
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發(fā)送
/// </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[]中讀取數(shù)據(jù)
/// </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這一結(jié)構(gòu)所占用的字節(jié)數(shù)
/// </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執(zhí)行命令是否成功。0:執(zhí)行成功, 其它:錯(cuò)誤碼
/// </summary>
public byte Result
{
get
{
return _result;
}
set
{
_result = value;
}
}
/// <summary>
/// 保留,最多8個(gè)字節(jié)
/// </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>
/// 序列號(hào), 參見(jiàn): 3.4序列號(hào)的定義, 12字節(jié)
/// </summary>
public class SequenceNumber
{
//保存的值將是網(wǎng)絡(luò)字節(jié)順序的值
private uint _part1;
private uint _part2;
private uint _part3;
private static uint _Sequence = 0; //用于第3部分,序號(hào)計(jì)數(shù)
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>
/// 將另一個(gè)序列號(hào)賦值給自已, 這在消息應(yīng)答時(shí)用
/// </summary>
/// <param name="r"></param>
public void Assign(SequenceNumber r)
{
this._part1 = r._part1;
this._part2 = r._part2;
this._part3 = r._part3;
}
/// <summary>
/// 返回所占用的字節(jié)數(shù)
/// </summary>
/// <returns></returns>
public int GetLength()
{
return 12;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -