📄 cms_wtp.c
字号:
}
cmsInsertPackage(psn, (unsigned short)(octstr_len(msg->wdp_datagram.user_data) - 4) );
cmsWtpSarPregress.curQuantity++;
event->RcvSegResult.psn = psn;
WTPGlobalMachine->psn =psn;
event->user_data = octstr_copy( msg->wdp_datagram.user_data, 4L, octstr_len(msg->wdp_datagram.user_data) - 4 );
}
return event;
}
else
{
wtp_re_send_ack(WTPGlobalMachine);
}
}
#else
{
unsigned char psn = 0;
psn = (CMS_S32)octstr_get_char(msg->wdp_datagram.user_data, 3L);
if(WTPGlobalMachine)
{
if (psn == (WTPGlobalMachine->psn +1) )
{
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 )
{
if ((first_octet & 0x06 ) == 0x00) //means gtr ttr : 0 0,is the segment result PUD which is not the last packet.
event->RcvSegResult.gtr_ttr = 0x0;
else if((first_octet & 0x06 ) == 0x02) /*last packet*/
event->RcvSegResult.gtr_ttr = 0x01;
else if ((first_octet & 0x06 ) == 0x04) /*last packet in a group*/
event->RcvSegResult.gtr_ttr = 0x02;
/* else
//cms_debug("Error!%s\n","impossible!");*/
event->RcvSegResult.psn = psn;
WTPGlobalMachine->psn = psn;
event->user_data = octstr_copy( msg->wdp_datagram.user_data, 4L, octstr_len(msg->wdp_datagram.user_data) - 4 );
}
else
//cms_debug("warning!%s\n","The CON is not 0 in the arrived PUD head.There are TPIs but you have no procedure!");
return event;
}
else if(tag_rid && (psn == WTPGlobalMachine->psn)) //the redundant re-transmit
{
wtp_re_send_ack(WTPGlobalMachine);
}
}
}
#endif
break;
case NOT_ALLOWED:
return event;
break;
/*result PDU is used by first segment of a segmented message, too. */
case RESULT:
#ifdef __CMS_TOOLKIT__
if(WTPGlobalMachine->get_first==1)
return event;
if(octstr_get_char(msg->wdp_datagram.user_data, 3L)==0x04)
WTPGlobalMachine->get_first=1;
#endif
/* means gtr ttr : 1 1,sar not supported.gtr ttr : 0 1,the last packet */
if ((first_octet & 0x06 ) == 0x06 || (first_octet & 0x06 ) == 0x02)
{
event = wtp_event_create(RcvResult);
event->RcvResult.tid = tid;
event->RcvResult.gtr_ttr = 0x01;
event->user_data = octstr_copy( msg->wdp_datagram.user_data, 3L, octstr_len(msg->wdp_datagram.user_data) - 3 );
}
else if( (first_octet & 0x06 ) == 0x04 ) //means gtr ttr : 1 0,is the result PUD followed by segmented result PDU.
{
event = wtp_event_create(RcvResult);
event->RcvResult.tid = tid;
/* last packet in a group */
event->RcvResult.gtr_ttr = 0x02;
event->user_data = octstr_copy( msg->wdp_datagram.user_data, 3L, octstr_len(msg->wdp_datagram.user_data) - 3 );
}
else if( (first_octet & 0x06 ) == 0x00 )/* means gtr ttr : 0 0,is the result PUD followed by segmented result PDU. */
{
event = wtp_event_create(RcvResult);
event->RcvResult.tid = tid;
//event->RcvResult.seg_result_head = 0;
event->RcvResult.gtr_ttr = 0x00;
event->user_data = octstr_copy( msg->wdp_datagram.user_data, 3L, octstr_len(msg->wdp_datagram.user_data) - 3 );
////cms_debug("%s\n","Warning!The data received data gtr ttr is 0 0.");
}
return event;
case INVOKE:
event = unpack_invoke(tid,msg);
return NULL;
case ACK://2003.8.19
{
CMS_U8 psn = 0;
CMS_U8 oct = 0;
CMS_U8 tip_continue = 0;
if((first_octet & 0x80) && (msg->wdp_datagram.user_data->len >3))
{
int i = 3;
tip_continue = 1;
while(tip_continue)
{
CMS_U8 oct_b = 0;
oct = octstr_get_char(msg->wdp_datagram.user_data, i);
oct_b = oct;
if((oct_b & 0x80) == 0x80)
tip_continue = 1;
else
tip_continue = 0;
oct_b = (oct & 0x78)>>3 ;
if(oct_b == 0x00)//err tpi
{
int tpi_len = 0;
tpi_len = oct & 0x03;
i += (tpi_len+1);
}
else if(oct_b == 0x01) //info tpi
{
int tpi_len = 0;
tpi_len = oct & 0x03;
i += (tpi_len+1);
}
else if(oct_b == 0x02) //option tpi
{
int tpi_len = 0;
tpi_len = oct & 0x03;
i += (tpi_len+1);
}
else if(oct_b == 0x03) //psn tpi
{
int tpi_len = 0;
tpi_len = oct & 0x03;
//psn only one octet
psn = octstr_get_char(msg->wdp_datagram.user_data, i+1);
i += (tpi_len+1);
}
else
tip_continue = 0;
}
}
return unpack_ack(tid, first_octet,psn);
}
break;
case ABORT:
fourth_octet = octstr_get_char(msg->wdp_datagram.user_data, 3L);
if (fourth_octet == -1)
{
return event;
}
return unpack_abort(msg, tid, first_octet, fourth_octet);
break;
case NEGATIVE_ACK:
break;
default:
{
event = wtp_event_create(RcvErrorPDU);
event->RcvErrorPDU.tid = tid;
return event;
}
break;
} /* switch */
return NULL;
} /* function */
/*
* Feed an event to a WTP state machine. Handle all errors yourself, do not
* report them to the caller. Note: Do not put {}s of the else block inside
* the macro definition (it ends with a line without a backlash).
*/
CMS_VOID wtp_handle_event(WTPMachine *machine, WTPEvent *event)
{
//WSPEvent *wsp_event = NULL;
////CmsDebugFunc((unsigned char*)"8888888",(short)0,(void*)NULL);
if(!machine && !event)
{
////cms_debug("error!%s","wtp machine is null or wtp event is null!");
return;
}
if(!machine && event)
{
if(event->type !=TimerTO_A && event->type !=TimerTO_R && event->type !=TimerTO_W)
{
wtp_event_destroy(event);
event = NULL;
}
return;
}
if (WTPWorking == 1)
{
append_to_event_queue(machine, event);
return;
}
WTPWorking = 1;
//////cms_trace("-start-wtp");
do {
//////cms_trace("wtp state front:%d\r\n",WTPGlobalMachine->state);
//////cms_trace("wtp event:%d\r\n",event->type);
////CmsDebugFunc((unsigned char*)"start wtp state ",(short)4,(void*)&(WTPGlobalMachine->state));
////CmsDebugFunc((unsigned char*)"event",(short)4,(void*)&(event->type));
#define STATE_NAME(state)
#define ROW(wtp_state, event_type, condition, action, next_state) \
{ \
struct event_type *e; \
e = &event->event_type; \
if (machine->state == wtp_state && \
event->type == event_type && \
(condition)) \
{ \
action \
machine->state = next_state; \
goto end; \
} \
} /* end of ROW */
#include "Cms_WTPStateDecl.h"
end:
if(event->type !=TimerTO_A && event->type !=TimerTO_R && event->type !=TimerTO_W && event->type !=TimerTO_N)
{
wtp_event_destroy(event);
event = NULL;
}
//////cms_trace("-mid-wtp");
//////cms_trace("wtp state tail:%d\r\n",WTPGlobalMachine->state);
////CmsDebugFunc((unsigned char*)"end wtp state ",(short)4,(void*)&(WTPGlobalMachine->state));
/*if(machine->InvokeEvent)
{
wtp_event_destroy(machine->InvokeEvent);
machine->InvokeEvent = NULL;
}*///20003.04.18
event = remove_from_event_queue(machine);
} while (event != NULL);
WTPWorking = 0;
return;
}
CMS_U64 wtp_tid_next(CMS_VOID)
{
return ++next_tid;
}
/*
* Iniatilizes the global lock for inserting and removing machines. If machines
* list is busy, just wait.
*/
WTPMachine *wtp_machine_create_empty(CMS_VOID)
{
WTPMachine *machine = (WTPMachine *)malloc(sizeof(WTPMachine));
//static WTPMachine wtpmac;
//machine=&wtpmac;
#define INTEGER(name) machine->name = 0
#define ENUM(name) machine->name = WTP_NULL
#define OCTSTR(name) machine->name = octstr_create_empty()
#define QUEUE(name) machine->name = NULL
#define CHARARR(name) memset(machine->name,0,sizeof(machine->name));
#define CHARARR8(name) memset(machine->name,0,sizeof(machine->name));//2003.10.30
#define MACHINE(field) field
#include "Cms_WTPMachineDecl.h"
#ifdef __CMS_TOOLKIT__
memset(&cmsWtpSarPregress,0,sizeof(cmsWtpSarPregress));
#endif
return machine;
}
/*
* Create a new WTPMachine for a given transaction, identified by the five-tuple
* in the arguments. In addition, update the transaction class field of the
* machine.
*/
WTPMachine *wtp_machine_create(Octstr *source_address,
CMS_S64 source_port, Octstr *destination_address,
CMS_S64 destination_port, CMS_S64 tid, CMS_S64 tcl)
{
WTPMachine *machine;
machine = wtp_machine_create_empty();
machine->tid = tid;
machine->tcl = tcl;
return machine;
}
//2003.5.7 主要是wtp machine 中有个变量InvokeEvent,是用来重传的WTP事件,在WTP状态机
//销毁时也要销毁
void wtp_machine_destroy(WTPMachine *machine)
{
////cms_debug("wtp machine destroyed ### ### ###\n\n","");
if(!machine)
return;
#define INTEGER(name)
#define ENUM(name)
#define CHARARR(name)
#define CHARARR8(name) //2003.10.30
#define OCTSTR(name) \
octstr_destroy(machine->name); \
machine->name = NULL;
#define QUEUE(name) \
wtp_event_destroy(machine->name); \
machine->name = NULL;
#define MACHINE(field) field
#include "Cms_WTPMachineDecl.h"
free(machine);
}
/*
* Packs a wsp event. Fetches flags and user data from a wtp event. Address
* five-tuple and tid are fields of the wtp machine.
*/
/*--Shawn 2002-12-25*/
WSPEvent *pack_wsp_event(WSPEventType wsp_name, WTPEvent *wtp_event,
WTPMachine *machine)
{
WSPEvent *event = wsp_event_create(wsp_name);
switch (wsp_name)
{
case TRInvokeConfirmation:
break;
case TRAbortIndication:
/*event->TRAbortIndication.abort_code = (CMS_S32)
wtp_event->RcvAbort.abort_reason;*/
break;
case TRResultIndication:
//event->TRResultIndication.user_data = wtp_event->user_data;
if(WTPGlobalMachine->seg_pdu)
event->TRResultIndication.user_data = WTPGlobalMachine->seg_pdu;
/*if(wtp_event->RcvResult.seg_result_head ==0)
event->TRResultIndication.tag_total_data = 1;
else
event->TRResultIndication.tag_total_data = 0;*/
//wtp_event->user_data=NULL;
WTPGlobalMachine->seg_pdu = NULL;
break;
default:
break;
}
return event;
}
/*
* Append an event to the event queue of a WTPMachine.
*/
static CMS_VOID append_to_event_queue(WTPMachine *machine, WTPEvent *event)
{
if (machine->event_queue_head == NULL)
{
machine->event_queue_head = event;
machine->event_queue_tail = event;
event->next = NULL;
}
else
{
machine->event_queue_tail->next = event;
machine->event_queue_tail = event;
event->next = NULL;
}
}
/*
* Return the first event from the event queue of a WTPMachine, and remove
* it from the queue. Return NULL if the queue was empty.
*/
static WTPEvent *remove_from_event_queue(WTPMachine *machine)
{
WTPEvent *event;
if (machine->event_queue_head == NULL)
event = NULL;
else
{
event = machine->event_queue_head;
machine->event_queue_head = event->next;
if (machine->event_queue_head == NULL)
machine->event_queue_tail = NULL;
event->next = NULL;
}
return event;
}
/*
* Every message type uses the second and the third octets for tid. Bytes are
* already in host order. Note that the iniator turns the first bit off, so we do
* have a genuine tid.
*/
static CMS_S64 deduce_tid(Msg *msg)
{
CMS_S64 first_part,second_part, tid;
first_part = octstr_get_char(msg->wdp_datagram.user_data, 1L);
second_part = octstr_get_char(msg->wdp_datagram.user_data, 2L);
tid = first_part;
tid = (tid<<8) + second_part;
return tid;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -