📄 transmit.pas
字号:
end;
SubmitLen := sizeof(TSMGPSubmit2011) + sizeof(TSMGPSubmit203) - 252 - 21 * (MAx_UserNumber - count) + SMGPSubmit203.MsgLength + 34; //34长度是可选参数中的三种 linkID submitmsgtype, spdealresult
//包头和包体1
with SMGPSubmit2011 do
begin
Head.PacketLength := winsock.Htonl(SubmitLen);
Head.RequestID := winsock.Htonl(Submit);
Head.SequenceID := winsock.Htonl(sSequence);
body.MsgType := rSubmit.sSubmit.MsgType;
body.NeedReport := rSubmit.sSubmit.NeedReport;
body.Priority := rSubmit.sSubmit.Priority;
body.MsgFormat := rSubmit.sSubmit.MsgFormat;
strpcopy(body.ServiceID, rSubmit.sSubmit.ServiceID);
strpcopy(body.FeeType, rSubmit.sSubmit.FeeType);
strpcopy(body.FeeCode, rSubmit.sSubmit.FeeCode);
strpcopy(body.FixedFee, rSubmit.sSubmit.FixedFee);
body.MsgFormat := rSubmit.sSubmit.MsgFormat;
strpcopy(body.ValidTime, rSubmit.sSubmit.ValidTime);
strpcopy(body.ATTime, rSubmit.sSubmit.ATTime);
end;
//===========================================================
SetLength(SocketBuff, SubmitLen);
FillChar(SocketBuff[0], SubmitLen, 0);
move(SMGPSubmit2011, SocketBuff[0], 74);
move(SMGPSubmit203, SocketBuff[74], 43);
move(SMGPSubmit203.DestTermID, SocketBuff[74 + 43], 21 * count);
move(SMGPSubmit203.MsgLength, SocketBuff[74 + 43 + 21 * count], 1);
move(SMGPSubmit203.MsgContent, SocketBuff[74+ 43 + 21 * count + 1], SMGPSubmit203.MsgLength);
move(SMGPSubmit203.Reserve, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength], 8);
//封装可选参数
FillChar(SMGPTLVLinkID_tag,sizeof(TSMGPTLVLinkID_tag), 0);
SMGPTLVLinkID_tag.Tag := winsock.htons(TLV_Lab_LinkID);
SMGPTLVLinkID_tag.Length:=winsock.htons(20);
// move(rSubmit.sSubmit.LinkID, SMGPTLVLinkID_tag.Value, 20);
strpcopy(SMGPTLVLinkID_tag.Value, rSubmit.sSubmit.LinkID);
move(SMGPTLVLinkID_tag, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength+8], 24);
FillChar(SMGPTLV_tag,sizeof(TSMGPTLV_tag),0);
SMGPTLV_tag.Tag:=winsock.htons(TLV_Lab_SubmitMsgType);
SMGPTLV_tag.Length:=winsock.htons(1);
SMGPTLV_tag.Value := rSubmit.sSubmit.SubmitMsgType;
move(SMGPTLV_tag, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength+8 + 24], 5);
FillChar(SMGPTLV_tag,sizeof(TSMGPTLV_tag),0);
SMGPTLV_tag.Tag:=winsock.htons(TLV_Lab_SPDealReslt);
SMGPTLV_tag.Length:=winsock.htons(1);
SMGPTLV_tag.Value:=0;
move(SMGPTLV_tag, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength+8 + 24+5], 5);
Result := HostToNet(SMGPSubmit2011.Head.SequenceID); //返回包序列号
end;
procedure TTransmit.ReceiveHead;
var
Head: TSMGPHead;
CTRequestID: Longword;
CTsequence: Longword;
Len: Longword;
begin
FillChar(Head, sizeof(TSMGPHead), 0);
if CTDeliver.Connected then
if CTDeliver.WaitForData(timeout) then
if sizeof(TSMGPHead) = CTDeliver.ReceiveBuf(Head, sizeof(TSMGPHead)) then
begin
Active_test_time := now;
CTRequestID := winsock.Htonl(Head.RequestID); //请求命令
Len := winsock.Htonl(Head.PacketLength); //消息长度
CTsequence := winsock.Htonl(Head.SequenceID); //序列号
ReceiveBody(CTRequestID, CTsequence, Len);
end;
end;
procedure TTransmit.AddSyncOrdCelMsg(aDeliver: TCTDeliver;const LinkID:string);
var
PSubmit: PxSubmit;
srcMsg, ServiceID, MsgContent:string;
begin
srcMsg:=Copy(aDeliver.MsgContent, 0, aDeliver.MsgLength);
DealWithSyncMsgCont(srcMsg, ServiceID, MsgContent);
new(PSubmit);
PSubmit^.Resend := 0;
PSubmit^.SequenceID := 0;
PSubmit^.Then_DateTime := 0;
PSubmit^.sSubmit.Mid := 'syc'+Formatdatetime('MMDDHHNNSS',now());
PSubmit^.sSubmit.MsgType := 6;
PSubmit^.sSubmit.NeedReport := 0;
PSubmit^.sSubmit.Priority := 0;
PSubmit^.sSubmit.ServiceID := ServiceID;//业务代码用短信内容体里的业务代码
PSubmit^.sSubmit.FeeType := '0';
PSubmit^.sSubmit.FeeCode := '0';
PSubmit^.sSubmit.FixedFee := '0';
PSubmit^.sSubmit.MsgFormat := 15;
PSubmit^.sSubmit.SrcTermID := aDeliver.DestTermID;
PSubmit^.sSubmit.ChargeTermID := aDeliver.SrcTermID;
PSubmit^.sSubmit.DestTermIDCount := 1;
PSubmit^.sSubmit.DestTermID := aDeliver.SrcTermID;
PSubmit^.sSubmit.MsgLength := Length(MsgContent);
PSubmit^.sSubmit.LinkID := LinkID;
PSubmit^.sSubmit.MsgContent := MsgContent;//StringReplace(aSubmit.MsgContent, #13, '', [rfReplaceAll]); //去除回车符
PSubmit^.sSubmit.SubmitMsgType := 15; //正常的点播信息
SubmitList.Add(PSubmit);
end;
procedure TTransmit.DealWithSyncMsgCont(const msgcontent: string;
var ServiceID, MsgContPart: string);
var
pos1,pos2:integer;
begin
// DG+空格+业务代码+双空格+受惠用户的终端号码+冒号+用户输入的内容
// QX+空格+业务代码+双空格+受惠用户的终端号码+冒号+用户输入的内容
if msgcontent ='00000' then
begin
ServiceID := msgcontent;
MsgContPart := msgcontent;
exit;
end;
pos1:=AnsiPos(#32, msgcontent);
pos2:=AnsiPos(#32#32, msgcontent);
ServiceID := MidStr(msgcontent, pos1+1, pos2-pos1-1);
pos1:= AnsiPos(':', msgcontent);
MsgContPart:= MidStr(msgcontent, 1, pos1-1);// 截取冒号前面得字串
end;
//截取用户输入得短信内容,
function TTransmit.GetInstruct(const msgcontent: string): string;
var
pos:integer;
begin
if msgcontent ='00000' then //正向取消所有业务得时候
begin
result:= msgcontent;
exit;
end;
pos:=AnsiPos(':', msgcontent);
if pos=0 then
result:= msgcontent
else
result:=strutils.RightStr(msgcontent, length(msgcontent)-pos);
end;
procedure TTransmit.ReceiveBody(CTRequestID, CTsequence, Len: Longword);
var
xLogin_resp: TSMGPLogin_resp;
SPResponse: PResponse;
xDeliver: TCTDeliver;
ErrMsg: array of char;
Status: Longword;
isRep: byte;
Mid: string;
begin
FillChar(xLogin_resp, sizeof(TSMGPLogin_resp), 0);
FillChar(xDeliver, sizeof(TCTDeliver), 0);
if CTDeliver.Connected then
begin
if Active_test_resp = CTRequestID then
begin {//电信发送链路测试回复}
StatuTxt := '【' + datetimetostr(now) + '】Active_Test_Resp 电信回复链路正常...' + inttostr(CTsequence);
LogList.AddLog('08' + StatuTxt);
showstatu;
if (MinutesBetween(now, LastSendWarnMsgTime) >= NoReceiveDeliver) and (MinutesBetween(now, ReceiveDeliverTime) >= NoReceiveDeliver) and (SendWarn) and (Counter < SendCount) then
begin
LogList.AddLog('10' + '电信网关于上次上行或登陆时间' + datetimetostr(ReceiveDeliverTime) + '到目前时间' + datetimetostr(now) + '已经超过' + inttostr(MinutesBetween(now, ReceiveDeliverTime)) + '分钟没有上行,请相关人员注意运行情况(系统将连续提醒' + inttostr(SendCount) + '次)');
inc(Counter);
if Counter = SendCount then
begin
LastSendWarnMsgTime := now;
Counter := 0;
end;
end;
end
else if Deliver = CTRequestID then
begin {//上行短信}
ReceiveDeliver(CTsequence, Len);
{ReceiveDeliverTime := now;
if 69 = CTDeliver.ReceiveBuf(xDeliver, 69) then
if xDeliver.MsgLength = CTDeliver.ReceiveBuf(xDeliver.MsgContent, xDeliver.MsgLength) then
if 8 = CTDeliver.ReceiveBuf(xDeliver.Reserve, 8) then
begin
SP_Deliver_Resp(xDeliver.Msgid, CTsequence); //上行短信回馈CP-->CT
isRep := xDeliver.IsReport;
if isRep = 1 then
WriteReport(xDeliver.Msgid, xDeliver.MsgContent)
else
begin
SaveToDeliverList(xDeliver);
synchronize(AddCou);
ShowDeliver(xDeliver);
end;
end; }
end
else if Submit_resp = CTRequestID then
begin {回馈报告Submit_response}
if CTDeliver.ReceiveBuf(CTSubmit_Resp, sizeof(TSMGPDeliver_Resp)) = sizeof(TSMGPDeliver_Resp) then
begin
Status := HostToNet(CTSubmit_Resp.Status);
if ((Status > 0) and (Status < 10)) or (Status = 39) then //返回这些代码的时候重发短信
ReSubmit(CTsequence, Status)
else if Status = 0 then
begin //电信网关正确接收
if not DeleteMT(CTsequence, Mid) then //删除缓冲区短信 并返回MID
Statustr := '【' + datetimetostr(now) + '】删除缓冲区短信时没有返回正确的MID';
new(SPResponse);
SPResponse^.Mid := Mid;
strpcopy(SPResponse^.Submit_resp.Msgid, BCDToHex(CTSubmit_Resp.Msgid, sizeof(CTSubmit_Resp.Msgid)));
SPResponse^.Submit_resp.Status := Status;
ResponseList.Add(SPResponse); //放入下行回馈队列中
Statustr := '[' + datetimetostr(now) + ']Submit_Resp:';
Statustr := Statustr +'<CTsequence>' +inttostr(CTsequence) + #32;
Statustr := Statustr +'<Mid>' + Mid + #32;
Statustr := Statustr +'<Msgid>' + SPResponse^.Submit_resp.Msgid + #32;
Statustr := Statustr +'<Status>' + inttostr(Status);
LogList.AddLog('02' + Statustr);
synchronize(upmemo);
end
else
begin //返回其他错误代码
DeleteMT(CTsequence, Mid); //删除缓冲区短信
Statustr := '【' + datetimetostr(now) + '】Submit_Resp:' + Mid + '返回状态=' + inttostr(Status) + ',短消息已经被删除';
LogList.AddLog('09' + Statustr);
synchronize(upmemo);
end;
end;
end
else if Active_test = CTRequestID then
begin {电信发送上行链路检测包}
StatuTxt := '【' + datetimetostr(now) + '】CT-->SPActiveTest 电信发送链路测试 ' + inttostr(CTsequence);
showstatu;
ActiveTest_Resp(CTsequence);
end
else if Exit_resp = CTRequestID then
begin {退出回复}
CTDeliver.Close;
DCanExit := True;
TransmitExit := False;
SockCanExit := True; ;
StatuTxt := '【' + datetimetostr(now()) + '】ExitCT --> 退出与中国电信的连接';
LogList.AddLog('11' + StatuTxt);
showstatu;
end
else
begin //错误的包头命令字
try
setlength(ErrMsg, Len - 12);
CTDeliver.ReceiveBuf(ErrMsg, Len - 12);
ErrMsg := nil;
except
end;
StatuTxt := '【' + datetimetostr(now()) + '】接收到类型错误的消息包';
showstatu;
end;
end;
end;
function TTransmit.ReceiveTLVMsg(const MsgLen: integer; var LinkID:string;var DealReslt:byte):byte;
var
tmpbuf:array of char;
tag, Len:word;
pos:integer;
value:array of char;
begin
SetLength(tmpbuf,MsgLen);
result:=0;
DealReslt:=0;
if CTDeliver.ReceiveBuf(tmpbuf[0], MsgLen) = MsgLen then //接收所有可选参数
begin
pos:=0;
while(pos < MsgLen)do
begin
Len:=0;
tag:=0;
Move(tmpbuf[pos], tag, 2);
Move(tmpbuf[pos+2], Len, 2);
tag:=htons(tag);//标签
len:=htons(len);
SetLength(value,len);
Move(tmpbuf[pos+4], value[0], Len);
case tag of
TLV_Lab_LinkID:
begin
//CopyMemory(@LinkID, @value, len);
setLength(LinkID, len);
Move(value[0],LinkID[1], len);
end;
TLV_Lab_SubmitMsgType:// 13 是同步定购, 15 是同步定购回复 0是正常上行
begin
//CopyMemory(@Result, @Value, 1);
Move(value[0], Result, 1);
end;
TLV_Lab_SPDealReslt: //同步定购处理结果 0 成功,1 失败
begin
//CopyMemory(@DealReslt, @Value,1);
Move(value[0], DealReslt, 1);
end;
end;
value:=nil;
inc(pos,4 + Len);
end;
end;
tmpbuf:=nil;
end;
procedure TTransmit.ReceiveDeliver(CTsequence, Len: Longword);
var
xDeliver: TCTDeliver;
isRep: byte;
LinkID:string;
SubmitMsgType,DealResult:byte;
Msg:string;
begin
FillChar(xDeliver, sizeof(TCTDeliver), 0);
ReceiveDeliverTime := now;
Counter := 0;
if 69 = CTDeliver.ReceiveBuf(xDeliver, 69) then
if xDeliver.MsgLength = CTDeliver.ReceiveBuf(xDeliver.MsgContent, xDeliver.MsgLength) then
if 8 = CTDeliver.ReceiveBuf(xDeliver.Reserve, 8) then
begin //再收可选参数
if (len - sizeof(CTSMSHeader) > 77+ xDeliver.MsgLength) then
begin //接收可选参数,输入参数是 可选参数总长度, LinkID, DealResult==处理结果
SubmitMsgType := ReceiveTLVMsg(len - (89 + xDeliver.MsgLength), LinkID, DealResult);
end;
SP_Deliver_Resp(xDeliver.Msgid, CTsequence); //上行短信回馈CP-->CT
isRep := xDeliver.IsReport;
if isRep = 1 then {//状态报告}
WriteReport(xDeliver.Msgid, xDeliver.MsgContent)
else
begin {//正常的上行短信/或用户拆机停机 信息}
case SubmitMsgType of
13://需要回复下行, SubmitMsgType = 15,LinkID也需要, 内容体为"DG+空格+业务代码+双空格+受惠用户的终端号码
//还需要再把短信内容只取用户输入的内容部分
begin //正向定制,取消
AddSyncOrdCelMsg(xDeliver, LinkID);//写入submit队列,
//上行短信内容改为用户输入内容
msg:=Copy(xDeliver.MsgContent,0, xDeliver.MsgLength);
FillChar(xDeliver.MsgContent,sizeof(xDeliver.MsgContent),0);
StrpCopy(xDeliver.MsgContent, GetInstruct(msg));
end;
15://反向定制,取消 回复,需要把 ReSycQX+1个空格+ 上内容 + 1个空格 + DealReslt
begin
msg:=Copy(xDeliver.MsgContent,0, xDeliver.MsgLength);
FillChar(xDeliver.MsgContent,sizeof(xDeliver.MsgContent),0);
StrpCopy(xDeliver.MsgContent, 'ReSyc '+ msg + #32 + inttostr(DealResult));
end;
end;
SaveToDeliverList(xDeliver, LinkID);
synchronize(AddCou);
showDeliver(xDeliver,LinkID);
end;
{try
fs:=Tfilestream.create( 'd:\Stream\D'+formatdatetime('ddhhnnss',now)+'.txt',fmCreate );
fs.WriteBuffer(xDeliver,sizeof(xDeliver));
finally
fs.free;
end;}
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -