📄 wtp.cpp
字号:
#include "WSP.H"
#include "WTP.H"
#include "UDP.H"
#include "TIMER.H"
// wap gateway host and port
char g_host[20];
int g_port;
// wtp tid
int g_tid = 0;
// segment invoke sequence number
// int g_seg_num = 0;
///////////////////////////// private function define//////////////////////////////
// get tid
static int GetTid();
// pack invoke pdu header
static int PackInvokePduHeader(char *data, int len);
// pack invoke pdu header
static int PackSegInvokePduHeader(char *data, int len, int first, int last, int seq);
// pack ack pdu header
static int PackAckPdu(char *data, int len);
// pack segment ack pdu header
static int PackSegAckPdu(char *data, int len, int seq);
// parse result pdu
static int ParseResultPdu(char *data, int len, int *pdu_type, int *seq);
// parse ack pdu
static int ParseSegAckPdu(char *data, int len, int *seq);
///////////////////////////////////public function///////////////////////////////
// wtp init
int WtpInit(char *host, int port)
{
int ret = 0;
memset(g_host, 0, 20);
memcpy(g_host, host, strlen(host));
g_port = port;
// udp init
ret = UDPInit(host, port);
return ret;
}
// invoke request
int WtpInvokeReq(char *data, int len)
{
char pdu[1400];
int header_len;
int ret = 0;
memset(pdu, 0, 1400);
// pack invoke pdu header
header_len = PackInvokePduHeader(pdu, 1400);
// append data
memcpy(pdu + header_len, data, len);
// udp output
ret = UDPSendData(pdu, header_len + len);
return ret;
}
// segment invoke request
int WtpSegInvokeReq(char *data, int len)
{
int ret = 0;
char pdu[1400]; //the max wtp length pdu is 1400
int first = 1;
int seq = 0;
memset(pdu, 0, 1400);
// 4 byte left for wtp header
while (len/1396)
{
// pack segment invoke pdu header
// the first packet is different form others
PackSegInvokePduHeader(pdu, 0, first, 0, seq);
// append data
memcpy(pdu + 4, data, 1396);
// udp output
if (!UDPSendData(pdu, 1400))
{
return 0;
}
// wait for ack...
if (!WtpAck(NULL, 0, seq))
{
return 0;
}
first = 0;
seq ++;
data = data + 1396;
len = len - 1396;
memset(pdu, 0, 1400);
}
// pack segment invoke pdu header, the last packet
PackSegInvokePduHeader(pdu, 0, first, 1, seq);
// append data
memcpy(pdu + 4, data, len);
// udp output
if (!UDPSendData(pdu, len + 4))
{
return 0;
}
// wait for result...
return 1;
}
// abort
int WtpAbort()
{
return 1;
}
// invoke result
int WtpInvokeResult(char *data, int len)
{
int ret = 0;
char buffer[1460];
char ack[5];
int gtr_ttr = 0;
int seq = 0;
int pdu_type = 0;
memset(buffer, 0, 1460);
memset(ack, 0, 5);
while (ret == 0)
{
// udp input
ret = UDPRecvData(buffer, 1460);
if (ret <= 0)
{
ret = 0;
continue;
}
//parse result pdu
gtr_ttr = ParseResultPdu(buffer, ret, &pdu_type, &seq);
switch (gtr_ttr)
{
case 0x00: //not last packet
if (pdu_type == RESULT)
{
memcpy(data, buffer + 3, 10);
}
break;
case 0x01: //last packet of message
if (seq == 0)
{
if (pdu_type == RESULT)
{
memcpy(data, buffer + 3, 10);
}
printf("WTP Recv Result\r\n");
PackAckPdu(ack, 3);
printf("WTP Send Ack\r\n");
UDPSendData(ack, 3);
}
else
{
printf("WTP Recv Result\r\n");
PackSegAckPdu(ack, 5, seq);
printf("WTP Send Ack\r\n");
UDPSendData(ack, 5);
}
return 1;
case 0x02: //last packet of group
printf("WTP Recv Result\r\n");
PackSegAckPdu(ack, 5, seq);
printf("WTP Send Ack\r\n");
UDPSendData(ack, 5);
break;
}
ret = 0;
}
return 0;
}
// receive ack
int WtpAck(char *data, int len, int seq)
{
int ret = 0;
int seq_num;
// the recv buffer
// 100 is enough for ack pdu
char buffer[100];
while (ret == 0)
{
// udp input
ret = UDPRecvData(buffer, 100);
if (ret <= 0)
{
ret = 0;
continue;
}
//parse ack pdu
ret = ParseSegAckPdu(buffer, 0, &seq_num);
// receive ack && the sequence is right
if (ret && seq_num == seq)
{
return 1;
}
}
return 0;
}
// wtp close
int WtpClose()
{
int ret;
g_tid = 0;
ret = UDPClose();
return ret;
}
//////////////////////////// private function////////////////////////////////
// get tid
static int GetTid()
{
g_tid++;
return g_tid;
}
// pack invoke pdu header
static int PackInvokePduHeader(char *data, int len)
{
int tid;
tid = GetTid();
// pdu type invoke
// no tpi
// last packet of message
// first transmission
data[0] = 0x0a;
// tid
data[1] = 0x00;
data[2] = (char)tid;
// class 2
// user ack
data[3] = 0x12;
return 4;
}
// pack invoke pdu header
static int PackSegInvokePduHeader(char *data, int len, int first, int last, int seq)
{
int tid;
if (first) //the first segment invoke
{
tid = GetTid();
// pdu type invoke
// no tpi
// last packet of group
// first transmission
data[0] = 0x0c;
// tid
data[1] = 0x00;
data[2] = (char)tid;
// class 2
// user ack
data[3] = 0x12;
}
else if (last) //the last segment invoke
{
tid = g_tid;
// pdu type segment invoke
// no tpi
// last packet of message
// first transmission
data[0] = 0x2a;
// tid
data[1] = 0x00;
data[2] = (char)tid;
// sequence number
data[3] = (char)seq;
}
else //the last packet of group
{
tid = g_tid;
// pdu type segment invoke
// no tpi
// last packet of group
// first transmission
data[0] = 0x2c;
// tid
data[1] = 0x00;
data[2] = (char)tid;
// sequence number
data[3] = (char)seq;
}
return 4;
}
// pack ack pdu header
static int PackAckPdu(char *data, int len)
{
// pdu type ack
// no tpi
// first transmission
data[0] = 0x18;
// tid
data[1] = 0x00;
data[2] = (char)g_tid;
return 3;
}
// pack segment ack pdu header
static int PackSegAckPdu(char *data, int len, int seq)
{
// pdu type ack
// no tpi
// first transmission
data[0] = 0x98;
// tid
data[1] = 0x00;
data[2] = (char)g_tid;
data[3] = 0x19;
data[4] = (char)seq;
return 1;
}
// parse result pdu
static int ParseResultPdu(char *data, int len, int *pdu_type, int* seq)
{
char type;
char gtr_ttr;
// get pdu type
type = data[0] >> 3;
type = type & 0x07;
*pdu_type = type;
// result pdu or segment result pdu
if (type != 0x02 && type != 0x06)
{
return 3;
}
// get tid
if (data[2] != (char)g_tid)
{
return 3;
}
// get gtr_ttr
gtr_ttr = data[0] >> 1;
gtr_ttr = gtr_ttr & 0x03;
if (type == 0x02 && gtr_ttr == 0x01)
{
*seq = 0;
return gtr_ttr;
}
if (type == 0x02 && gtr_ttr == 0x00)
{
*seq = 0;
return gtr_ttr;
}
if (type == 0x06 && gtr_ttr == 0x00)
{
*seq = 0;
return gtr_ttr;
}
if (type == 0x06 && gtr_ttr == 0x01)
{
*seq = (int)data[3];
return gtr_ttr;
}
if (type == 0x06 && gtr_ttr == 0x02)
{
*seq = (int)data[3];
return gtr_ttr;
}
return 3;
}
// parse ack pdu
static int ParseSegAckPdu(char *data, int len, int *seq)
{
char type;
char tpi;
//char seq_num;
//char tid;
// get pdu type
type = data[0] >> 3;
type = type & 0x07;
// ack pdu
if (type != 0x03)
{
return 0;
}
// get tid
if (data[2] != (char)g_tid)
{
return 0;
}
// get tpi
tpi = data[0] >> 7;
if (tpi != 0)
{
*seq = (int)data[4]; // get sequence number
}
else
{
*seq = 0;
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -