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

📄 cms_wtpsend.c

📁 wap 协议栈 包括1.2 和2.0 由c开发 基于brew平台
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************

 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 + -