⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cngpstructs.pas

📁 支持CMPP/SGIP/SMGP/CNGP/SMPP协议的多功能网关模拟器:概述:基于CMPP v3.0 v2.0协议, SGIP v1.2协议...实现了正向订制/退订、反向订制/退订接口。同时提供
💻 PAS
字号:
unit CNGPStructs;

interface

uses
    Windows, WinSock, General;

type

    (********  CNGP message structures  ********)

    CNGPTLV = packed record
        ParameterTag: Word;
        Length: Word;
        Value: Byte;
    end;

    (*
        Message header: 16Bytes
        Message body(required): variable length
        Message body(optional): TLV -- Tag-Length-Value
    *)

    PHeader = ^CNGPHeader;
    CNGPHeader = packed record
        Total_Length: DWord; //Total length of message, including message header.
        Command_Id: DWord; //Command identifier
        Command_Status: DWord; //Command status
        Sequence_Id: DWord; //Sequence NO., increased by 1
    end;

    (*
        CNGP message format:

        CNGPMessage = (packed) record
            Header: CNGPHeader;
            Body: CNGPBodyRequired;
            TLV: CNGPBodyOptional;
        end;
    *)

    PLogin = ^CNGPLogin;
    CNGPLogin = packed record
        Header: CNGPHeader;
        ClientId: array[0..9] of Char; //SP identifier
        AuthenticatorClient: array[0..15] of Byte; //MD5(ClinetID + #0 * 7 + ShareKey + Timestamp)
        LoginMode: Byte; //0: Send, 1: Receive, 2: Send and receive, other: Reserved
        TimeStamp: DWord; //mmddhhnnss, 10 decimal digits, right alignment
        Version: Byte; //Client version, higher 4 bits: Major, lower 4 bits: Minor
    end;

    PLoginResp = ^CNGPLoginResp;
    CNGPLoginResp = packed record
        Header: CNGPHeader;
        AuthenticatorServer: array[0..15] of Byte; //MD5(Status + AuthenticatorClient + ShareKey)
        Version: Byte; //Server version
    end;

    //ShareKey, also named SharedSecret, 15 bytes max

    PSubmit = ^CNGPSubmit;
    CNGPSubmit = packed record
        Header: CNGPHeader;
        spid: array[0..9] of Char; //Same as the ClientId field of CNGPLogin structure
        SubType: Byte; //0: Cancel, 1: Subs/order, 2: Order resp, 3: Subs MT
        NeedReport: Byte; //0: No report, 1: Need report
        Priority: Byte; //0..3
        ServiceId: array[0..9] of Char;
        FeeType: array[0..1] of Char;
        //00: Free, 01: By msg, 02: Monthly, 03: Monthly max, 04: Charge req, 05: CR Charge
        FeeUserType: Char; //Charge from: 0: DestTerm, 1: SrcTerm, 2: SP, 3: ChargeNo
        FeeCode: array[0..5] of Char; //Fee (cent) per message
        MsgFormat: Byte;
        ValidTime: array[0..16] of Char;
        AtTime: array[0..16] of Char;
        SrcTermId: array[0..20] of Char;
        ChargeTermId: array[0..20] of Char;
        DestTermIdCount: Byte;
        DestTermId: array[0..99] of array[0..20] of Char;
        MsgLength: Byte;
        msgContent: array[0..255] of Char;
        ProtocolId: CNGPTLV;
    end;

    PSubmitResp = ^CNGPSubmitResp;
    CNGPSubmitResp = packed record
        Header: CNGPHeader;
        MsgId: array[0..9] of Char;
        CongestionState: CNGPTLV;
    end;

    PDeliver = ^CNGPDeliver;
    CNGPDeliver = packed record
        Header: CNGPHeader;
        MsgId: array[0..9] of Char;
        IsReport: Byte; //0: No, 1: Yes
        MsgFormat: Byte;
        RecvTime: array[0..13] of Char; //yyyymmddhhnnss
        SrcTermId: array[0..20] of Char;
        DestTermId: array[0..20] of Char;
        MsgLength: Byte;
        msgContent: array[0..255] of Char;
        ProtocolId: CNGPTLV;
    end;

    PDeliverResp = ^CNGPDeliverResp;
    CNGPDeliverResp = packed record
        Header: CNGPHeader;
        MsgId: array[0..9] of Char;
        CongestionState: CNGPTLV;
    end;

    PActiveTest = ^CNGPActiveTest;
    CNGPActiveTest = CNGPHeader;
    PActiveTestResp = ^CNGPActiveTestResp;
    CNGPActiveTestResp = CNGPHeader;
    PExit = ^CNGPExit;
    CNGPExit = CNGPHeader;
    PExitResp = ^CNGPExitResp;
    CNGPExitResp = CNGPHeader;

    (*
        CNGP report is the content of deliver package when the IsReport field value is 1

        CNGPReport = (packed) record
            id: char[10];
            sub: char[3] = '001';
            dlvrd: char[3] = '001';
            submit_date: char[10];
            done_date: char[10];
            stat: char[7];
            err: char[3];
            txt: CNGPReportText;
        end;

        CNGPReportText = (packed) record
            len: char[3];
            content: char[17];
        end;
    *)

    PReport = ^CNGPReport;
    CNGPReport = packed record
        id: array[0..9] of Char;
        sub: array[0..2] of Char;
        dlvrd: array[0..2] of Char;
        submit_date: array[0..9] of Char;
        done_date: array[0..9] of Char;
        stat: array[0..6] of Char;
        err: array[0..2] of Char;
        txt: array[0..19] of Char;
    end;


    // 给定信息,构造CNGP消息头
procedure BuildHeader(var Header: CNGPHeader; totalLength, commandId, commandStatus: DWord);
// 把给定的Deliver消息中的msgContent解析成Report结构
procedure ParseReport(deliver: CNGPDeliver; var rpt: CNGPReport);

implementation

uses SysUtils;

var
    publicSeqId: DWord = 0;
    lock: TRTLCriticalSection;

procedure LockSeqId;
begin
    EnterCriticalSection(lock);
end;

procedure UnlockSeqId;
begin
    LeaveCriticalSection(lock);
end;

procedure BuildHeader(var Header: CNGPHeader; totalLength, commandId, commandStatus: DWord);
begin
    // 现在,消息头中的序号,由数据库生成
    //LockSeqId;
    //Header.Sequence_Id := htonl(publicSeqId);
    Header.Total_Length := htonl(totalLength);
    Header.Command_Id := htonl(commandId);
    Header.Command_Status := htonl(commandStatus);
    {    if publicSeqId >= 4294967295 then
            publicSeqId := 0
        else
            Inc(publicSeqId);
    }
        //UnlockSeqId;
end;

procedure ParseReport(deliver: CNGPDeliver; var rpt: CNGPReport);
var
    i: integer;
begin
    // 逐个解析出Report中的元素
    i := ArrPos('id:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.id[0], @deliver.msgContent[i + 3], 10);
    i := ArrPos('sub:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.sub[0], @deliver.msgContent[i + 4], 3);
    i := ArrPos('dlvrd:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.dlvrd[0], @deliver.msgContent[i + 6], 3);
    i := ArrPos('submit_date:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.submit_date[0], @deliver.msgContent[i + 12], 10);
    i := ArrPos('done_date:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.done_date[0], @deliver.msgContent[i + 10], 10);
    i := ArrPos('stat:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.stat[0], @deliver.msgContent[i + 5], 7);
    i := ArrPos('err:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.err[0], @deliver.msgContent[i + 4], 3);
    i := ArrPos('txt:', deliver.msgContent);
    if i >= 0 then
        CopyMemory(@rpt.txt[0], @deliver.msgContent[i + 4], 20);
end;

//
initialization
    InitializeCriticalSection(lock);

finalization
    DeleteCriticalSection(lock);

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -