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

📄 cms_wtpsend.c

📁 wap 协议栈 包括1.2 和2.0 由c开发 基于brew平台
💻 C
📖 第 1 页 / 共 3 页
字号:
					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 + -