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

📄 cms_wtp.c

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