📄 cms_wtp.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 : malloc.c
Last Modify : 06/22/2002
******************************************************************************/
#include "string.h"
#include "Cms_WAPMain.h"
#include "Cms_WAPMalloc.h"
#include "Cms_WTP.h"
#include "Cms_WTPGLOBALVARIABLE.h"
#include "Cms_WTPTimer.h"
#include "Cms_WAPStatus.h"
#include "cms_wtpsend.h"
CMS_U64 next_tid = 0;
WTPMachine * WTPGlobalMachine;
extern unsigned char redirect_host[8];
extern unsigned short redirect_port;
struct WTPTimer WTPGlobalTimer[WTP_TIMER_NUMBER]; /* TimerTO_A, TimerTO_R, TimerTo_W , TimerTo_N */
CMS_S32 WTPRCR = 0; /* 计数器RCR重发 */
CMS_S32 WTPAEC = 0; /* 计数器确认*/
CMS_S32 WTPNACK = 0; /* nack的计数器 */
CMS_S32 HoldOn = 0;
CMS_S32 WTPWorking = 0; /* 检测wtp状态机是否在工作 */
#define DEFAULT_WTP_SIZE 3*1024
#ifdef __CMS_TOOLKIT__
WTP_Sar_Progress cmsWtpSarPregress;
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
extern CMS_BOOL Cms_UDPInput(CMS_VOID);
extern void wtp_re_send_ack(WTPMachine *machine);
extern void checkIfPageInWTPpacket(const char *buf);
/*****************************************************************************
*
* Prototypes of internal functions:
*
* Create an uniniatilized wtp state machine.
*/
static WTPMachine *wtp_machine_create_empty(CMS_VOID);
static CMS_VOID append_to_event_queue(WTPMachine *machine, WTPEvent *event);
static WTPEvent *remove_from_event_queue(WTPMachine *machine);
static CMS_S64 deduce_tid(Msg *msg);
static CMS_S8 deduce_pdu_type(CMS_U8 octet);
static CMS_S32 protocol_version(CMS_U8 octet);
static WTPEvent *unpack_ack(CMS_S64 tid, CMS_U8 octet,CMS_U8 psn); //2003.8.19
static WTPEvent *unpack_abort(Msg *msg, CMS_S64 tid, CMS_U8 first_octet, CMS_U8 fourth_octet);
static WTPEvent *unpack_result(CMS_S64 tid, Msg *msg);
static WTPEvent *unpack_invoke(CMS_S64 tid, Msg *msg);
static WTPEvent *unpack_invoke_flags(WTPEvent *event, Msg *msg, CMS_S64 tid,
CMS_U8 first_octet, CMS_U8 fourth_octet);
static CMS_S32 first_segment(WTPEvent *event);
/***macro action*****/
static void RcvSegResult_Action(WTPMachine *machine,WTPEvent *event);
static void null_trir_allsend_rw(WTPMachine *machine,WTPEvent *event);
static void null_trir_segsend_rw(WTPMachine *machine,WTPEvent *event);
static void wssaw_abort_1_null(WTPMachine *machine,WTPEvent *event);
static void wssaw_rcverrpdu_1_null(WTPMachine *machine,WTPEvent *event);
static void wssaw_rcvabort_1_null(WTPMachine *machine,WTPEvent *event);
static void wssaw_ra_21_wssaw(WTPMachine *machine,WTPEvent *event);
static void wssaw_tim_rcrltmax_wssaw(WTPMachine *machine,WTPEvent *event);
static void wssaw_tim_rcreqmax_null(WTPMachine *machine,WTPEvent *event);
static void wssaw_ra_lastpacket_wssaw(WTPMachine *machine,WTPEvent *event);
static void rw_tra_2_null(WTPMachine *machine,WTPEvent *event);
static void rw_rcverrpdu_2_null(WTPMachine *machine,WTPEvent *event);
static void rw_ra_2_rw(WTPMachine *machine,WTPEvent *event);
static void rw_ra_tve_rw(WTPMachine *machine,WTPEvent *event);
static void rrw_trrr_1_null(WTPMachine *machine,WTPEvent *event);
static void wrrw_ra_1_null(WTPMachine *machine, WTPEvent *event);
static void wrrw_tra_1_null(WTPMachine *machine, WTPEvent *event);
static void wrrw_timeout_aeceqmax_null(WTPMachine *machine, WTPEvent *event);
static void wt_rr_1_wt(WTPMachine *machine,WTPEvent *event);
static void wwt_tim_1_null(WTPMachine *machine,WTPEvent *event);
static void rw_rr_gt1_rrw(WTPMachine *machine,WTPEvent *event);
#ifdef __SELECTIVE_RETRANSMISSION__
static void wrw_timn_wrw(WTPMachine *machine,WTPEvent *event);
#endif
static void rw_rr_gt2_rrw(WTPMachine *machine,WTPEvent *event);
static void rw_rr_gt0_rrw(WTPMachine *machine,WTPEvent *event);
static void rw_ra_1_null(WTPMachine *machine,WTPEvent *event);
static void wrw_tim_rcrltmax_wrw(WTPMachine *machine, WTPEvent *event);
static void wrw_tim_rcrltmaxtidok_wrw(WTPMachine *machine, WTPEvent *event);
static void wrw_tim_rcreqmax_wrw(WTPMachine *machine, WTPEvent *event);
static void wrw_timn_wrw_max(WTPMachine *machine, WTPEvent *event);
static void clear_transaction();
/*
* Packs a wsp event. Fetches flags and user data from a wtp event. Address
* five-tuple and tid are fields of the wtp machine.
*/
WSPEvent *pack_wsp_event(WSPEventType wsp_name, WTPEvent *wtp_event,
WTPMachine *machine);
#ifdef __CMS_TOOLKIT__
/* 根据当前Package的序号得到偏移量 */
int cmsGetPackageOffset(unsigned char index)
{
WTP_Get_Package *currentPackage=cmsWtpSarPregress.sarPackage;
while(currentPackage)
{
if(currentPackage->currentIndex==index)
return currentPackage->nextPackageOffset;
else
currentPackage=currentPackage->next;
}
return 0;
}
/* 将当前Package的信息插入到SAR过程 */
void cmsInsertPackage(unsigned char index,unsigned short len)
{
WTP_Get_Package * currentPackage = cmsWtpSarPregress.sarPackage;
while(currentPackage)
{
if(currentPackage->currentIndex<=index)
{
if(currentPackage->next)
{
if(currentPackage->next->currentIndex<index)
currentPackage=currentPackage->next;
else
{
WTP_Get_Package *newPackage=NULL,*nextPackage=NULL;
newPackage=(WTP_Get_Package*)malloc(sizeof(WTP_Get_Package));
memset(newPackage,0,sizeof(WTP_Get_Package));
newPackage->currentIndex=index;
newPackage->next=currentPackage->next;
newPackage->prev=currentPackage;
newPackage->nextPackageOffset=currentPackage->nextPackageOffset+len;
nextPackage=currentPackage->next;
while(nextPackage)
{
nextPackage->nextPackageOffset+=len;
nextPackage=nextPackage->next;
}
currentPackage->next=newPackage;
return;
}
}
else
{
WTP_Get_Package *newPackage=NULL;
newPackage=(WTP_Get_Package*)malloc(sizeof(WTP_Get_Package));
memset(newPackage,0,sizeof(WTP_Get_Package));
newPackage->currentIndex=index;
newPackage->prev=currentPackage;
newPackage->nextPackageOffset=currentPackage->nextPackageOffset+len;
currentPackage->next=newPackage;
return;
}
}
else
{
WTP_Get_Package* newPackage=NULL,*nextPackage=NULL;
newPackage=(WTP_Get_Package*)malloc(sizeof(WTP_Get_Package));
memset(newPackage,0,sizeof(WTP_Get_Package));
newPackage->currentIndex=index;
newPackage->next=currentPackage;
newPackage->nextPackageOffset=len;
currentPackage->prev=newPackage;
nextPackage=currentPackage;
while(nextPackage)
{
nextPackage->nextPackageOffset+=len;
nextPackage=nextPackage->next;
}
cmsWtpSarPregress.sarPackage=newPackage;
return;
}
}
currentPackage=(WTP_Get_Package*)malloc(sizeof(WTP_Get_Package));
memset(currentPackage,0,sizeof(WTP_Get_Package));
currentPackage->currentIndex=index;
currentPackage->nextPackageOffset=len;
cmsWtpSarPregress.sarPackage=currentPackage;
return;
}
/* 判断是否已经得到全部的数据报,是,返回TRUE */
CMS_BOOL cmsIfGetAll(void)
{
if(cmsWtpSarPregress.curQuantity==cmsWtpSarPregress.totalPackage)
return TRUE;
else
return FALSE;
}
/* 判断某需要的包是否已经收到,是,返回TRUE */
CMS_BOOL cmsIfPackageExist(unsigned char index)
{
WTP_Get_Package *currentPackage=cmsWtpSarPregress.sarPackage;
while(currentPackage)
{
if(currentPackage->currentIndex==index)
return TRUE;
else
currentPackage=currentPackage->next;
}
return FALSE;
}
void cmsFreeSarProgress(void)
{
WTP_Get_Package *currentPackage=cmsWtpSarPregress.sarPackage, *tempPackage=NULL;
while(currentPackage)
{
tempPackage=currentPackage->next;
free(currentPackage);
currentPackage=tempPackage;
}
cmsWtpSarPregress.sarPackage = NULL;
}
#ifdef __SELECTIVE_RETRANSMISSION__
int cmsGetMaxPackageNum(void)
{
WTP_Get_Package *currentPackage=cmsWtpSarPregress.sarPackage,*tempPackage=NULL;
while(currentPackage)
{
tempPackage=currentPackage;
currentPackage=currentPackage->next;
}
return tempPackage->currentIndex;
}
CMS_BOOL cmsIfPackageContinuous(void)
{
WTP_Get_Package *currentPackage=cmsWtpSarPregress.sarPackage,*tempPackage=NULL;
if(!currentPackage)
return TRUE;
if(currentPackage->currentIndex != 0)
{
return FALSE;
}
while(currentPackage)
{
tempPackage=currentPackage->next;
if(tempPackage)
{
if(tempPackage->currentIndex != currentPackage->currentIndex+1)
{
return FALSE;
}
}
currentPackage=tempPackage;
}
return TRUE;
}
#endif
#endif
/******************************************************************************
*
* EXTERNAL FUNCTIONS:
*/
WTPEvent *wtp_event_create(enum event_name type)
{
WTPEvent *event;
event = (WTPEvent *)malloc((CMS_U32)sizeof(WTPEvent));
memset(event,0,sizeof(WTPEvent));
event->type = type;
event->next = NULL;
event->user_data = NULL;
#define INTEGER(name) p->name = 0
#define OCTSTR(name) p->name = NULL
#define EVENT(type, field) { struct type *p = &event->type; field }
#include "Cms_WTPEventsDecl.h"
return event;
}
/*
* Note: We must use p everywhere (including events having only integer
* fields), otherwise we get a compiler warning. (Defs will be removed when we have
* an integrated memory freeing policy).
*/
CMS_VOID wtp_event_destroy(WTPEvent *event)
{
if (event != NULL)
{
octstr_destroy(event->user_data);
event->user_data = NULL;
if(event->big_data)
{
/* store the vfile_to_send,don't free it.
free it at memory file system destroy_mms_mem_file_info */
event->big_data->data = NULL;
event->big_data->len = 0;
}
octstr_destroy(event->big_data);
event->big_data = NULL;
#define INTEGER(name) p->name = 0
#define OCTSTR(name) octstr_destroy(p->name)
#define EVENT(type, field) { struct type *p = &event->type; field }
#include "Cms_WTPEventsDecl.h"
free(event);
event = NULL;
}
}
/*
* Transfers data from fields of a message to fields of WTP event. User data has
* the host byte order. Updates the log and sends protocol error messages. Re-
* assembles segmented messages, too.
*
* Return event, when we have a single message; NULL, when we have a segment.
*/
WTPEvent *wtp_unpack_wdp_datagram(Msg *msg)
{
static WTPEvent *event = NULL;
CMS_U8 first_octet = 0,fourth_octet = 0;
CMS_S8 pdu_type = 0;
CMS_S64 tid = 0;
unsigned char tag_rid = 0;
event = NULL;
tid = deduce_tid(msg);
/* @tt
* 为了防止在一次新的交互过程中,
* 收到上一次网关发过来的数据,
* 检查数据包的tid,如果不等则不处理
* 收到的数据包,并且只有在wtp的状态
* 不为wtp_null的情况下才处理接收的
* 数据。以前是0xff
*/
if( (tid & 0x7fff) != WTPGlobalMachine->tid || WTP_NULL == WTPGlobalMachine->state )
{
//////cms_trace("error wtp_unpack_wdp_datagram: receive wrong tid package\n");
return event;
}
if (octstr_len(msg->wdp_datagram.user_data) < 3)
{
event = wtp_event_create(RcvErrorPDU);
event->RcvErrorPDU.tid = tid;
return event;
}
first_octet = octstr_get_char(msg->wdp_datagram.user_data, 0L);
pdu_type = deduce_pdu_type(first_octet);
tag_rid = first_octet & 0x01;
switch (pdu_type)
{
case SEGMENTED_RESULT:
#ifdef __CMS_TOOLKIT__
{
unsigned char psn=octstr_get_char(msg->wdp_datagram.user_data, 3L);
if(!cmsIfPackageExist(psn))
{
event = wtp_event_create(RcvSegResult);
/* if CON is 0,means NO TPIs followed by the result PDU head.the length of result PDU is 3.*/
if( (first_octet & 0x80) == 0x00 )
{
/* means gtr ttr : 0 0,is the segment result PUD which is not the last packet. */
if ((first_octet & 0x06 ) == 0x00)
event->RcvSegResult.gtr_ttr = 0x0;
else if((first_octet & 0x06 ) == 0x02) /*last packet*/
{
event->RcvSegResult.gtr_ttr = 0x01;
cmsWtpSarPregress.totalPackage=psn+1;
WTPGlobalMachine->get_last=1;
}
else if ((first_octet & 0x06 ) == 0x04) /*last packet in a group*/
{
event->RcvSegResult.gtr_ttr = 0x02;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -