📄 cms_wtpsend.c
字号:
wtp_handle_event(WTPGlobalMachine,wtp_event);
wsp_event = pack_wsp_event(TRAbortIndication, wtp_event, WTPGlobalMachine);
wsp_dispatch_event( WTPGlobalMachine, wsp_event);
}
}
if(wtp_recv_ack())
{
}
else
{
//wtp_retrans();
//now,we don't retransmit the missing packet but abort this transaction.
WTPEvent * wtp_event= NULL;
WSPEvent *wsp_event = NULL;
cms_debug("At the %d times group send,recv the Nack...\n",group_count);
wtp_event = wtp_event_create( TRAbort );
wtp_event->TRAbort.tid = WTPGlobalMachine->tid;
wtp_event->TRAbort.abort_type = PROVIDER ;/*wsp abort not wtp abort*/
wtp_event->TRAbort.abort_reason = WTPPROTOERR ;
wtp_handle_event(WTPGlobalMachine,wtp_event);
wsp_event = pack_wsp_event(TRAbortIndication, wtp_event, WTPGlobalMachine);
wsp_dispatch_event( WTPGlobalMachine, wsp_event);
}
#else
return;
#endif
}
}
}
#else
static CMS_VOID wtp_segment(WTPMachine *machine,WTPEvent *event)
{
CMS_U8 seq_num = 0;
CMS_U8 tag_rid = 0;
Msg s_msg;
char data_to_send[WTP_PACKET_SIZE+4];/* 4 means invoke pdu and seg invoke pdu head len */
int sended_len = 0;
int total_len = 0;
Octstr oct_to_send;
memset(&oct_to_send,0,sizeof(Octstr));
if(!event ||!event->big_data)
return;
memset(data_to_send,0,sizeof(data_to_send));
memset(&s_msg,0,sizeof(Msg));
sended_len = machine->sended_len;
total_len = event->big_data->len+event->user_data->len;
if(event->type == RcvInvoke)
{
if(event->big_data->data && sended_len <total_len && (total_len-sended_len)>WTP_PACKET_SIZE)
{
if(sended_len<event->user_data->len)
{
memset(data_to_send,0,sizeof(data_to_send));
memcpy(data_to_send+4,event->user_data->data,event->user_data->len);//the head 4 bytes for pdu head
sended_len += event->user_data->len;
if(sended_len<WTP_PACKET_SIZE)
{
void* p_start = 0;
int len_remain = 0;
p_start = (void*)(data_to_send+4+event->user_data->len);
len_remain = sizeof(data_to_send)-4-event->user_data->len;
memcpy((void*)p_start,event->big_data->data,len_remain);
sended_len += len_remain;
}
}
else
{
void* p_start = 0;
int len_remain = 0;
p_start = (void*)(event->big_data->data+sended_len-event->user_data->len);
len_remain = sizeof(data_to_send)-4;
memset(data_to_send,0,sizeof(data_to_send));
memcpy(data_to_send+4,p_start,len_remain);//the head 4 bytes for pdu head
sended_len += len_remain;
}
/* build a seg pdu */
produce_seg_pdu_head(data_to_send,(unsigned char)event->RcvInvoke.packet_count,(unsigned char)event->RcvInvoke.seg_seq_num,tag_rid);
memset(machine->buff_of_retrans,0,sizeof(machine->buff_of_retrans));
machine->len_of_retrans = 0;
memcpy(machine->buff_of_retrans,data_to_send,sizeof(data_to_send));
machine->len_of_retrans = sizeof(data_to_send);
machine->buff_of_retrans[0] |= 0x01;
oct_to_send.data = (unsigned char*)data_to_send;
oct_to_send.len = sizeof(data_to_send);
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &oct_to_send;
event->RcvInvoke.packet_count--;
machine->psn = event->RcvInvoke.seg_seq_num;
event->RcvInvoke.seg_seq_num++;
put_msg_in_queue_2(&s_msg);
}
else
{
CMS_U8 packet_count = 1;
void *p_start = 0;
int len_remain = 0;
p_start = (void*)(event->big_data->data+sended_len-event->user_data->len);
len_remain = total_len-sended_len;
memset(data_to_send,0,sizeof(data_to_send));
memcpy(data_to_send+4,p_start,len_remain);
sended_len += len_remain;
/*build a seg pdu*/
produce_seg_pdu_head(data_to_send,packet_count,(unsigned char)event->RcvInvoke.seg_seq_num,tag_rid);
memset(machine->buff_of_retrans,0,sizeof(machine->buff_of_retrans));
machine->len_of_retrans = 0;
memcpy(machine->buff_of_retrans,data_to_send,len_remain+4);
machine->buff_of_retrans[0] |= 1;
machine->len_of_retrans = len_remain+4;
oct_to_send.data = (unsigned char*)data_to_send;
oct_to_send.len = len_remain+4;
s_msg.type = wdp_datagram;
s_msg.wdp_datagram.user_data = &oct_to_send;
event->RcvInvoke.packet_count--;
event->RcvInvoke.seg_seq_num++;
put_msg_in_queue_2(&s_msg);
sended_len = 0;
}
}
machine->sended_len = sended_len;
}
#endif
#if (!defined CMS_WAP_CENT_RELEASE) && (!defined CMS_WAP_CENT_DEBUG)
static CMS_BOOL wtp_recv_ack()
{
P_CMS_U8 data = NULL;
CMS_S32 len;
Octstr *os;
CMS_U8 first_octet;
Cms_UDPRecvData(&data,&len);
/*--Shawn 2003-01-09*/
if(len == 0)
return 0;
os=octstr_create_from_data(data, (CMS_S64)len);
if(os == NULL)
return 0;
first_octet = octstr_get_char(os, 0L);
octstr_destroy(os);
if(((first_octet>>3)&0x0f) == ACK)
{
cms_debug("%s\n","Received a ACK.");
return 1;
}
else if(((first_octet>>3)&0x0f)== NEGATIVE_ACK)
{
cms_debug("%s\n","Warning!Received is a NACK.");
return 0;
}
else
{
cms_debug("%s\n","Error!Recieved is not a ack or a nack!");
return 0;
}
}
#endif
/*====================================================================
* Function: wtp_pdu_concatenate
* Input: sdu :the sdu to be sent in a batch,which should be malloced and the are CMS_U8 0x00 means concatenation indication.
pdu :the pdu data to be sent in this batch.
* Return: 0 false;1 true
* Description:
* Author: Shawn Pan
* Date: 2002-12-25
* Revision history:
* modify reason:
* mender:
* modify date:
====================================================================*/
static CMS_U8 wtp_pdu_concatenate(Octstr *sdu,Octstr *pdu)
{
CMS_U8 first_len_oct = 0;
CMS_U8 second_len_oct = 0;
CMS_S64 temp = 0;
if (pdu->len > (CMS_S64)0x01<<16 - 1)
{
return 0;
}
if(pdu->len < 255)
{
octstr_append_char(sdu,pdu->len);
octstr_append_data(sdu,pdu->data,pdu->len);
}
else /*pdu len occupy 16 bits. and first bit is 1*/
{
temp = pdu->len;
second_len_oct = (CMS_U8)temp & 0xff;
first_len_oct = (CMS_U8)((temp>>8) & 0xff);
first_len_oct |= 0x80 ; /*The first bit is set to 1*/
octstr_append_char(sdu,first_len_oct);
octstr_append_char(sdu,second_len_oct);
octstr_append_data(sdu,pdu->data,pdu->len);
}
return 1;
}
/*====================================================================
* Function: pack_seg_invoke_pdu
* Input:
* Return: the invoke pdu which is followed by seg pdu.
* Description: You should mms_Free the returned ocstr which malloced in this function
* Author: Shawn Pan
* Date: 2002-12-25
* Revision history:
* modify reason:
* mender:
* modify date:
====================================================================*/
static Octstr* pack_seg_invoke_pdu()
{
CMS_U8 *octet = NULL;
Octstr *seg_pdu = NULL;
octet = (CMS_U8*)malloc(4);
memset(octet,0,4);
/* CON no TPIs,so is 0 */
/* PUD type is invoke */
octet[0] |=0x08;
/* GTR TTR */
octet[0] |=0x00;
/* rid */
octet[0] |=0x00;
insert_tid((CMS_U8*)octet, WTPGlobalMachine->tid);
/*version is 0
//TidNEW is 0
//RES RES is 0*/
octet[3] |= (WTPGlobalMachine->tcl&0x03);
//UP_flag is not set
//octet |=event->RcvInvoke.up_flag*0x10;
seg_pdu = octstr_create_from_data(octet,sizeof(octet));
return seg_pdu;
}
/*pdu_head should be a buffer with the size more the 4 bytes*/
static void produce_seg_pdu_head(char *pdu_head,CMS_U8 packet_count,CMS_U8 seq_num,CMS_U8 tag_rid)
{
CMS_U8 seg_pdu_head[4] ={0,0,0,0} ;
CMS_U16 temp;
/*First is invoke PDU.*//*is the first pdu but not the sole pdu*/
if (seq_num == 0 && packet_count !=1)
{
seg_pdu_head[0] |= 0x01<<3;
//grt ttr:1 0
seg_pdu_head[0] |= 0x04;
//rid
seg_pdu_head[0] |= tag_rid;
//tid
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[1] |= (temp & 0xff00);
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[2] |= (temp & 0x00ff);
//version TIDNew u/p RES RES tcl
seg_pdu_head[3] |= 0x12; //u/p is, 1 tcl is 2
}
else /*segment pdu*/
{
//con ;pdu type;GTR TTR;RID
//PDU TYPE segment PDU is 05.
seg_pdu_head[0] |= 0x05<<3;
//rid
seg_pdu_head[0] |= tag_rid;
//GTR TTR is 0 0 when is not the last packet,is 0 1 when is the last packet
if(packet_count==1)
seg_pdu_head[0] |= 0x02;
else /*if(WTP_PACKET_NUM_IN_GROUP == 1 ||
packet_count%WTP_PACKET_NUM_IN_GROUP == 1)
seg_pdu_head[0] |= 0x04;*/ /*the last packet in a group*/
/*else
seg_pdu_head[0] |= 0x00;*/
seg_pdu_head[0] |= 0x04; /*the last packet in a group*/
//RID is 0 when is not re-transmitting
//TID
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[1] |= (temp & 0xff00);
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[2] |= (temp & 0x00ff);
//seqence number
seg_pdu_head[3] |= seq_num;
}
memcpy(pdu_head,seg_pdu_head,sizeof(seg_pdu_head));
return;
}
static void insert_seg_pdu_head(Octstr*seg_pdu,CMS_U8 packet_count,CMS_U8 seq_num,CMS_U8 tag_rid)
{
CMS_U8 seg_pdu_head[4] ={0,0,0,0} ;
CMS_U16 temp;
/*First is invoke PDU.*//*is the first pdu but not the sole pdu*/
if (seq_num == 0 && packet_count !=1)
{
seg_pdu_head[0] |= 0x01<<3;
//grt ttr:1 0
seg_pdu_head[0] |= 0x04;
//rid
seg_pdu_head[0] |= tag_rid;
//tid
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[1] |= (temp & 0xff00);
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[2] |= (temp & 0x00ff);
//version TIDNew u/p RES RES tcl
seg_pdu_head[3] |= 0x12; //u/p is, 1 tcl is 2
}
else /*segment pdu*/
{
//con ;pdu type;GTR TTR;RID
//PDU TYPE segment PDU is 05.
seg_pdu_head[0] |= 0x05<<3;
//rid
seg_pdu_head[0] |= tag_rid;
//GTR TTR is 0 0 when is not the last packet,is 0 1 when is the last packet
if(packet_count==1)
seg_pdu_head[0] |= 0x02;
else /*if(WTP_PACKET_NUM_IN_GROUP == 1 ||
packet_count%WTP_PACKET_NUM_IN_GROUP == 1)
seg_pdu_head[0] |= 0x04;*/ /*the last packet in a group*/
/*else
seg_pdu_head[0] |= 0x00;*/
seg_pdu_head[0] |= 0x04; /*the last packet in a group*/
//RID is 0 when is not re-transmitting
//TID
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[1] |= (temp & 0xff00);
temp = (CMS_U16)WTPGlobalMachine->tid;
seg_pdu_head[2] |= (temp & 0x00ff);
//seqence number
seg_pdu_head[3] |= seq_num;
}
octstr_insert_data(seg_pdu,0,seg_pdu_head,sizeof(seg_pdu_head));
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -