📄 cms_wtpsend.c
字号:
/******************************************************************************
C M O D U L E F I L E
(c) Copyright MobileSoft Technology (NanJing) Co., LTD. 2001-2002
ALL RIGHTS RESERVED
*******************************************************************************
Project Name: WAP STACK Ver1.20
Written By : MobileSoft Technology
File Name : Cms_Malloc.c
Last Modify : 06/22/2002
******************************************************************************/
#include "Cms_WTPSend.h"
#include "Cms_WAPMsg.h"
#include "Cms_WAPBox.h"
extern WTPMachine * WTPGlobalMachine;
#ifdef __CMS_TOOLKIT__
extern WTP_Sar_Progress cmsWtpSarPregress;
#endif
extern WSPEvent *pack_wsp_event(WSPEventType wsp_name, WTPEvent *wtp_event,
WTPMachine *machine);
extern CMS_VOID put_msg_in_queue_2(Msg *msg);
extern CMS_BOOL Cms_UDPInput(CMS_VOID);
enum
{
ERROR_DATA = 0x00,
INFO_DATA = 0x01,
OPTION = 0x02,
PACKET_SEQUENCE_NUMBER = 0x03
};
/*****************************************************************************
*
* Prototypes of internal functions
*/
static Msg *pack_invoke(Msg *msg, WTPMachine *machine, WTPEvent *event);
static int pack_invoke_2(Msg *msg, WTPMachine *machine, WTPEvent *event);
static Msg *pack_abort(Msg *msg, CMS_S64 abort_type, CMS_S64 abort_reason, CMS_S32 tid);
static Msg *pack_stop(Msg *msg, CMS_S64 abort_type, CMS_S64 abort_reason, CMS_S64 tid);
static Msg *pack_ack(Msg *msg, CMS_S64 ack_type, WTPMachine *machine,
WTPEvent *event,CMS_U8 con,CMS_U8 tpi_type,Octstr *tpi);
static int pack_ack_2(Msg *msg, CMS_S64 ack_type, WTPMachine *machine,
WTPEvent *event,CMS_U8 con,CMS_U8 tpi_type,Octstr *tpi);
#ifdef __SELECTIVE_RETRANSMISSION__
static void pack_nack(unsigned char * buf,int *len,int tid);
#endif
/*****************************************************************************
*
* internal functions used by pack function
*/
static CMS_U8 insert_pdu_type(CMS_S32 type, CMS_U8 octet);
static CMS_U8 insert_gtr_ttr(CMS_U8 octet);/*--Shawn 2002-12-31*/
static CMS_U8 insert_rid(CMS_S64 attribute, CMS_U8 octet);
static CMS_VOID insert_tid(P_CMS_U8 pdu, CMS_S64 attribute);
static Msg *set_rid(Msg *msg, CMS_S64 rid);
static CMS_S64 message_rid(Msg *msg);
static CMS_U8 insert_abort_type(CMS_S32 abort_type, CMS_U8 octet);
static CMS_U8 indicate_ack_type(CMS_U8 ack_type, CMS_U8 octet);
static CMS_U8 indicate_variable_header(CMS_U8 octet);
static CMS_VOID wtp_segment(WTPMachine *machine,WTPEvent *event);
#if (!defined CMS_WAP_CENT_RELEASE) && (!defined CMS_WAP_CENT_DEBUG)
static CMS_BOOL wtp_recv_ack();
#endif
static CMS_U8 wtp_pdu_concatenate(Octstr *sdu,Octstr *pdu);
static Octstr* pack_seg_invoke_pdu(void);
static void produce_seg_pdu_head(char *pdu_head,CMS_U8 packet_count,CMS_U8 seq_num,CMS_U8 tag_rid);
static CMS_VOID insert_seg_pdu_head(Octstr*seg_pdu,CMS_U8 packet_count,CMS_U8 seq_num,CMS_U8 tag_rid);
/*****************************************************************************
*
* EXTERNAL FUNCTIONS:
*/
#if (!defined CMS_WAP_CENT_RELEASE) && (!defined CMS_WAP_CENT_DEBUG)
Msg *wtp_send_invoke(WTPMachine *machine, WTPEvent *event)
{
Msg * msg = NULL;
CMS_BOOL flag = 0;
if(event->user_data->len <= WTP_PACKET_SIZE)
{
msg = msg_create(wdp_datagram);
msg = pack_invoke(msg, machine, event);
put_msg_in_queue(msg);
#if (!defined CMS_WAP_CENT_RELEASE) && (!defined CMS_WAP_CENT_DEBUG)
flag = Cms_UDPInput();
if (flag == 0)/*received no data,timeout,create a abort event.*/
{
WTPEvent * wtp_event= NULL;
WSPEvent *wsp_event = NULL;
wtp_event = wtp_event_create( TRAbort );
wtp_event->TRAbort.tid = machine->tid;
wtp_event->TRAbort.abort_type = PROVIDER ;/*wsp abort not wtp abort*/
wtp_event->TRAbort.abort_reason = WTPPROTOERR ;
wtp_handle_event(WTPGlobalMachine,event);
wsp_event = pack_wsp_event(TRAbortIndication, wtp_event, machine);
wsp_dispatch_event( machine, wsp_event);
}
#else
return NULL;
#endif
}
else
{
//wtp_segment(event);
}
return msg;
}
#else
/* 当包小于WTP_PACKET_SIZE时,一次发送 */
Msg *wtp_all_send_invoke(WTPMachine *machine, WTPEvent *event)
{
Msg s_msg;
CMS_BOOL flag = 0;
unsigned char s_msg_data[WTP_MTU];
Octstr s_msg_oct;
memset(&s_msg,0,sizeof(Msg));
memset(s_msg_data,0,sizeof(s_msg_data));
memset(&s_msg_oct,0,sizeof(Octstr));
s_msg_oct.data = s_msg_data;
s_msg_oct.len = 0;
if(event->user_data->len <= WTP_PACKET_SIZE)
{
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &s_msg_oct;
pack_invoke_2(&s_msg, machine, event);
put_msg_in_queue_2(&s_msg);
}
return NULL;
}
/* 当包大于WTP_PACKET_SIZE时,分割发送 */
Msg *wtp_seg_send_invoke(WTPMachine *machine, WTPEvent *event) //wtp_send_invoke
{
wtp_segment(machine,event);
return NULL;
}
/* 重传 */
void wtp_re_send_invoke(WTPMachine *machine, WTPEvent *event)
{
Msg s_msg;
memset(&s_msg,0,sizeof(Msg));
if(machine && event)
{
if(event->type == RcvInvoke)
{
if(machine->buff_of_retrans[0])
{
Octstr oct;
memset(&oct,0,sizeof(Octstr));
oct.data = machine->buff_of_retrans;
oct.len = machine->len_of_retrans;
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &oct;
put_msg_in_queue_2(&s_msg);
}
}
}
return;
}
void wtp_re_send_ack(WTPMachine *machine)
{
Msg s_msg;
memset(&s_msg,0,sizeof(Msg));
if(machine )
{
if(machine->buff_of_retrans[0])
{
Octstr oct;
memset(&oct,0,sizeof(Octstr));
oct.data = machine->buff_of_retrans;
oct.len = machine->len_of_retrans;
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &oct;
put_msg_in_queue_2(&s_msg);
}
}
return;
}
#endif
/*
* Sends a message object, of wdp datagram type, having abort header as user
* data. Fetches address four-tuple from WTP machine, tid from wtp event, abort
* type and reason from direct input. Handles all errors by itself.
*/
CMS_VOID wtp_send_abort(CMS_S64 abort_type, CMS_S64 abort_reason, CMS_S32 tid)
{
Msg *msg = NULL;
msg = msg_create(wdp_datagram);
msg = pack_abort(msg, abort_type, abort_reason,tid);
if (msg == NULL)
{
return;
}
put_msg_in_queue(msg);
return;
}
CMS_VOID wtp_send_ack(CMS_S64 ack_type, WTPMachine *machine, WTPEvent *event,CMS_U8 con,CMS_U8 tpi_type,Octstr *tpi)
{
Msg s_msg;
unsigned char s_msg_data[WTP_MTU];
Octstr s_msg_oct;
memset(&s_msg,0,sizeof(Msg));
memset(s_msg_data,0,sizeof(s_msg_data));
memset(&s_msg_oct,0,sizeof(Octstr));
s_msg_oct.data = s_msg_data;
s_msg_oct.len = 0;
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &s_msg_oct;
pack_ack_2(&s_msg, ack_type, machine, event, con, tpi_type, tpi);/*--Shawn 2003-01-04*/
if (machine)
{
memset(machine->buff_of_retrans,0,sizeof(machine->buff_of_retrans));
machine->len_of_retrans = 0;
memcpy(machine->buff_of_retrans,s_msg.wdp_datagram.user_data->data,s_msg.wdp_datagram.user_data->len);
machine->len_of_retrans = s_msg.wdp_datagram.user_data->len;
machine->buff_of_retrans[0] |= 0x01;
}
put_msg_in_queue_2(&s_msg);
return;
}
#ifdef __SELECTIVE_RETRANSMISSION__
CMS_VOID wtp_send_nack(WTPMachine *machine)
{
Msg s_msg;
unsigned char s_msg_data[WTP_MTU];
Octstr s_msg_oct;
int tid = 0;
memset(&s_msg,0,sizeof(Msg));
memset(s_msg_data,0,sizeof(s_msg_data));
memset(&s_msg_oct,0,sizeof(Octstr));
s_msg_oct.data = s_msg_data;
s_msg_oct.len = 0;
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &s_msg_oct;
tid = machine->tid;
pack_nack((unsigned char *)s_msg_data, (int *)&(s_msg_oct.len),tid);
put_msg_in_queue_2(&s_msg);
return;
}
#endif
/*
the input param msg should pre-malloc space and msg.wdp_datagram.user_data.data
should be pre-malloc space.
*/
static int pack_invoke_2(Msg *msg, WTPMachine *machine, WTPEvent *event)
{
CMS_S32 octet;
CMS_U32 pdu_len;
CMS_U8 wtp_pdu[4] ;
octet = -42;
pdu_len = 4;
if(!msg ||!machine||!event)
{
return 0;
}
octet = (int)insert_pdu_type(INVOKE, (CMS_U8)octet);
octet = (int)insert_gtr_ttr((CMS_U8)octet);
octet = (int)insert_rid(0, (CMS_U8)octet);
wtp_pdu[0] = octet;
insert_tid(wtp_pdu, event->RcvInvoke.tid);
wtp_pdu[3] = (CMS_U8)(machine->tcl&0x03);
wtp_pdu[3] |=(CMS_U8)(event->RcvInvoke.up_flag<<4);
if(msg->wdp_datagram.user_data &&msg->wdp_datagram.user_data->data)
{
memcpy(msg->wdp_datagram.user_data->data,wtp_pdu,sizeof(wtp_pdu));
msg->wdp_datagram.user_data->len += sizeof(wtp_pdu);
if(event->user_data &&event->user_data->data)
{
memcpy(msg->wdp_datagram.user_data->data+sizeof(wtp_pdu),event->user_data->data,event->user_data->len);
msg->wdp_datagram.user_data->len +=event->user_data->len;
memset(machine->buff_of_retrans,0,sizeof(machine->buff_of_retrans));
machine->len_of_retrans = 0;
memcpy(machine->buff_of_retrans,msg->wdp_datagram.user_data->data,msg->wdp_datagram.user_data->len);
machine->buff_of_retrans[0] |=0x01;
machine->len_of_retrans = msg->wdp_datagram.user_data->len;
}
}
return 1;
}
/****************************************************************************
*
* INTERNAL FUNCTIONS:
*
* Packs a message object, of wdp datagram type, having result PDU as user
* data. Fetches SDU from WTP event, machine state information (are we
* resending the packet) from WTP machine. Handles all errors by itself.
*/
static Msg *pack_invoke(Msg *msg, WTPMachine *machine, WTPEvent *event)
{
CMS_S32 octet;
CMS_U32 pdu_len;
CMS_U8 wtp_pdu[4] ;
CMS_U8 wtp_pdu_for_retrans[4];
Octstr *pdu_for_retrans = NULL;
octet = -42;
pdu_len = 4;
msg->wdp_datagram.user_data = octstr_duplicate(event->user_data);
pdu_for_retrans = octstr_duplicate(event->user_data);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -