回退n帧协议(基于Opnet)

/* Process model C form file: Pro5_proc.pr.c */
/* Portions of this file copyright 1986-2008 by OPNET Technologies, Inc. */






/* This variable carries the header into the object file */
const char Pro5_proc_pr_c [] = "MIL_3_Tfile_Hdr_ 145A 30A modeler 7 4F82D889 4F82D889 1 microsof-d42869 Administrator 0 0 none none 0 0 none 0 0 0 0 0 0 0 0 1bcc 1                                                                                                                                                                                                                                                                                                                                                                                            ";
#include <string.h>






/* OPNET system definitions */
#include <opnet.h>






/* Header Block */


#define MAX_SEQ 7
#include "protocol.h"
#define network_layer_ready (op_intrpt_type() == OPC_INTRPT_STRM && op_intrpt_strm() == 0)
#define wait_for_init (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() == 0)
#define frame_arrival_intrpt (op_intrpt_type() == OPC_INTRPT_STRM && op_intrpt_strm()== 1)
#define time_out_intrpt (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() >=10 && op_intrpt_code()<=19 )


/* End of Header Block */


#if !defined (VOSD_NO_FIN)
#undef BIN
#undef BOUT
#define BIN FIN_LOCAL_FIELD(_op_last_line_passed) = __LINE__ - _op_block_origin;
#define BOUT BIN
#define BINIT FIN_LOCAL_FIELD(_op_last_line_passed) = 0; _op_block_origin = __LINE__;
#else
#define BINIT
#endif /* #if !defined (VOSD_NO_FIN) */






/* State variable definitions */
typedef struct
{
/* Internal state tracking for FSM */
FSM_SYS_STATE
/* State Variables */
Evhandle               handle_array[MAX_SEQ + 1]                       ;
int                     next_frame_to_send                              ;
int                     ack_expected                                    ;
int                     frame_expected                                  ;
Packet *               r                                               ; /* scratch variable */
int                     nbuffered                                       ; /* 用来输出当前在用的缓冲 */
int                     i                                               ; /* 用来在当前的数组中索引 */
Packet *               buffer[MAX_SEQ + 1]                             ;
int                     previous_data                                   ;
double                 delay                                           ;
} Pro5_proc_state;


#define handle_array             op_sv_ptr->handle_array
#define next_frame_to_send       op_sv_ptr->next_frame_to_send
#define ack_expected             op_sv_ptr->ack_expected
#define frame_expected           op_sv_ptr->frame_expected
#define r                       op_sv_ptr->r
#define nbuffered               op_sv_ptr->nbuffered
#define i                       op_sv_ptr->i
#define buffer                   op_sv_ptr->buffer
#define previous_data           op_sv_ptr->previous_data
#define delay                   op_sv_ptr->delay


/* These macro definitions will define a local variable called */
/* "op_sv_ptr" in each function containing a FIN statement. */
/* This variable points to the state variable data structure, */
/* and can be used from a C debugger to display their values. */
#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE
#define FIN_PREAMBLE_DEC Pro5_proc_state *op_sv_ptr;
#define FIN_PREAMBLE_CODE \
op_sv_ptr = ((Pro5_proc_state *)(OP_SIM_CONTEXT_PTR->_op_mod_state_ptr));




/* Function Block */


#if !defined (VOSD_NO_FIN)
enum { _op_block_origin = __LINE__ + 2};
#endif


static Boolean between(int a,int b,int c)
{
//如果b在a和c的范围之内就返回true
FIN(between(int a,int b,int c));
if(((a<=b) && (b<c)) || ((c<a) && (a<=b)) || ((b<c) && (c<a)))
{
FRET(OPC_TRUE);
}
else
{
FRET(OPC_FALSE);
}
}


void start_timer(int seq)
{
FIN(start_timer(int seq));
//规定10-19为时钟自中断
if(0 <= seq <= MAX_SEQ + 1)
{
handle_array[seq] = op_intrpt_schedule_self(op_sim_time() + 3.5,seq + 10);
//printf("start_timer\n");
}
else
{
printf("start_timer阶段seq溢出范围\n");
}
FOUT;
}


void stop_timer(int seq)
{
FIN(kill_timer(int seq));
if(0 <= seq <= MAX_SEQ + 1)
{
//if(op_ev_valid(handle_array[seq]) == OPC_TRUE)
//{
op_ev_cancel_if_pending(handle_array[seq]);
//printf("kill_timer %d\n",seq);
//}
}
else
{
printf("kill_timer阶段seq溢出范围\n");
}
FOUT;
}




static void send_data(int frame_nr,int frame_expected_r,double delay_time)
{
//构造和发送一个数据帧
Packet* pkptr;
int seq ;
int ack ;
FIN(send_data(int frame_nr,int frame_expected_r,double delay_time));
seq = frame_nr;
ack = (frame_expected_r + MAX_SEQ)%(MAX_SEQ+1);
//ack = (frame_expected_r)%(MAX_SEQ + 1);
pkptr = op_pk_copy(buffer[frame_nr]);
op_pk_nfd_set(pkptr,"seq",seq);
op_pk_nfd_set(pkptr,"ack",ack);
// printf("seq = %d,ack = %d\n",seq,ack);
op_pk_send_delayed(pkptr,0,delay_time);
start_timer(seq,delay_time);
FOUT;
}


static void enable_network_layer()
{
FIN(enable_network_layer());
op_strm_access(0);
FOUT;
}


static void disable_network_layer()
{
FIN(disable_network_layer());
op_strm_access(2);
FOUT;
}

















/* End of Function Block */


/* Undefine optional tracing in FIN/FOUT/FRET */
/* The FSM has its own tracing code and the other */
/* functions should not have any tracing.  */
#undef FIN_TRACING
#define FIN_TRACING


#undef FOUTRET_TRACING
#define FOUTRET_TRACING


#if defined (__cplusplus)
extern "C" {
#endif
void Pro5_proc (OP_SIM_CONTEXT_ARG_OPT);
VosT_Obtype _op_Pro5_proc_init (int * init_block_ptr);
void _op_Pro5_proc_diag (OP_SIM_CONTEXT_ARG_OPT);
void _op_Pro5_proc_terminate (OP_SIM_CONTEXT_ARG_OPT);
VosT_Address _op_Pro5_proc_alloc (VosT_Obtype, int);
void _op_Pro5_proc_svar (void *, const char *, void **);




#if defined (__cplusplus)
} /* end of 'extern "C"' */
#endif








/* Process model interrupt handling procedure */




void
Pro5_proc (OP_SIM_CONTEXT_ARG_OPT)
{
#if !defined (VOSD_NO_FIN)
int _op_block_origin = 0;
#endif
FIN_MT (Pro5_proc ());


{




FSM_ENTER ("Pro5_proc")


FSM_BLOCK_SWITCH
{
/*---------------------------------------------------------*/
/** state (init) enter executives **/
FSM_STATE_ENTER_UNFORCED (0, "init", state0_enter_exec, "Pro5_proc [init enter execs]")
FSM_PROFILE_SECTION_IN ("Pro5_proc [init enter execs]", state0_enter_exec)
{

Objid my_id;
int user_id;
previous_data = 0;
my_id = op_id_self();
my_id = op_topo_parent(my_id);
op_ima_obj_attr_get_int32(my_id,"user_id",&user_id);
op_ima_obj_attr_get(op_id_self(),"delay",&delay);


ack_expected = 0; //本地期望回应的帧
next_frame_to_send = 0; //下一个希望发送出去的帧
frame_expected = 0; //本地期望得到的帧
nbuffered = 0; //初始化的时候没有帧被缓冲
if(user_id == 0)
{
op_intrpt_schedule_self(op_sim_time() + 5,0);
}
else
{
op_intrpt_schedule_self(op_sim_time() + 5.25,0);
}
}
FSM_PROFILE_SECTION_OUT (state0_enter_exec)


/** blocking after enter executives of unforced state. **/
FSM_EXIT (1,"Pro5_proc")




/** state (init) exit executives **/
FSM_STATE_EXIT_UNFORCED (0, "init", "Pro5_proc [init exit execs]")




/** state (init) transition processing **/
FSM_PROFILE_SECTION_IN ("Pro5_proc [init trans conditions]", state0_trans_conds)
FSM_INIT_COND (wait_for_init)
FSM_DFLT_COND
FSM_TEST_LOGIC ("init")
FSM_PROFILE_SECTION_OUT (state0_trans_conds)


FSM_TRANSIT_SWITCH
{
FSM_CASE_TRANSIT (0, 1, state1_enter_exec, ;, "wait_for_init", "", "init", "wait", "tr_5", "Pro5_proc [init -> wait : wait_for_init / ]")
FSM_CASE_TRANSIT (1, 0, state0_enter_exec, ;, "default", "", "init", "init", "tr_3", "Pro5_proc [init -> init : default / ]")
}
/*---------------------------------------------------------*/






/** state (wait) enter executives **/
FSM_STATE_ENTER_UNFORCED (1, "wait", state1_enter_exec, "Pro5_proc [wait enter execs]")
FSM_PROFILE_SECTION_IN ("Pro5_proc [wait enter execs]", state1_enter_exec)
{
if(nbuffered < MAX_SEQ)
{
enable_network_layer();
//printf("nbuffered = %d  11\n",nbuffered);
}
else
{
//disable_network_layer();
//printf("nbuffered = %d  22\n",nbuffered);
}
}
FSM_PROFILE_SECTION_OUT (state1_enter_exec)


/** blocking after enter executives of unforced state. **/
FSM_EXIT (3,"Pro5_proc")




/** state (wait) exit executives **/
FSM_STATE_EXIT_UNFORCED (1, "wait", "Pro5_proc [wait exit execs]")




/** state (wait) transition processing **/
FSM_PROFILE_SECTION_IN ("Pro5_proc [wait trans conditions]", state1_trans_conds)
FSM_INIT_COND (network_layer_ready)
FSM_TEST_COND (frame_arrival_intrpt)
FSM_TEST_COND (time_out_intrpt)
FSM_DFLT_COND
FSM_TEST_LOGIC ("wait")
FSM_PROFILE_SECTION_OUT (state1_trans_conds)


FSM_TRANSIT_SWITCH
{
FSM_CASE_TRANSIT (0, 2, state2_enter_exec, ;, "network_layer_ready", "", "wait", "network_layer_ready", "tr_1", "Pro5_proc [wait -> network_layer_ready : network_layer_ready / ]")
FSM_CASE_TRANSIT (1, 3, state3_enter_exec, ;, "frame_arrival_intrpt", "", "wait", " frame_arrival", "tr_6", "Pro5_proc [wait ->  frame_arrival : frame_arrival_intrpt / ]")
FSM_CASE_TRANSIT (2, 4, state4_enter_exec, ;, "time_out_intrpt", "", "wait", "time_out", "tr_8", "Pro5_proc [wait -> time_out : time_out_intrpt / ]")
FSM_CASE_TRANSIT (3, 1, state1_enter_exec, ;, "default", "", "wait", "wait", "tr_16", "Pro5_proc [wait -> wait : default / ]")
}
/*---------------------------------------------------------*/






/** state (network_layer_ready) enter executives **/
FSM_STATE_ENTER_FORCED (2, "network_layer_ready", state2_enter_exec, "Pro5_proc [network_layer_ready enter execs]")
FSM_PROFILE_SECTION_IN ("Pro5_proc [network_layer_ready enter execs]", state2_enter_exec)
{
//网络层有一帧需要发送
Packet* pkptr;
Packet* pk_copy;

Objid my_id;
int user_id;
my_id = op_id_self();
my_id = op_topo_parent(my_id);
op_ima_obj_attr_get_int32(my_id,"user_id",&user_id);
//printf("user_id = %d\n",user_id);


//获取到这个帧,保存并发送一个新的帧
pkptr = op_pk_get(op_intrpt_strm()); //取得新的帧
pk_copy = op_pk_copy(pkptr);
buffer[next_frame_to_send] = pk_copy;
nbuffered = nbuffered + 1; //增加发送者的滑动窗口

//if(user_id == 0)
//{
/* printf("+++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("user_id = %d\n",user_id);
printf("next_frame_to_send %d\n",next_frame_to_send); */
//}


send_data(next_frame_to_send,frame_expected,0); //发送那一帧



inc(next_frame_to_send); //增加发送者的窗口边缘


}
FSM_PROFILE_SECTION_OUT (state2_enter_exec)


/** state (network_layer_ready) exit executives **/
FSM_STATE_EXIT_FORCED (2, "network_layer_ready", "Pro5_proc [network_layer_ready exit execs]")




/** state (network_layer_ready) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "network_layer_ready", "wait", "tr_2", "Pro5_proc [network_layer_ready -> wait : default / ]")
/*---------------------------------------------------------*/






/** state ( frame_arrival) enter executives **/
FSM_STATE_ENTER_FORCED (3, " frame_arrival", state3_enter_exec, "Pro5_proc [ frame_arrival enter execs]")
FSM_PROFILE_SECTION_IN ("Pro5_proc [ frame_arrival enter execs]", state3_enter_exec)
{
Packet* pkptr;
int seq;
int data;
int ack;

Objid my_id;
int user_id;
my_id = op_id_self();
my_id = op_topo_parent(my_id);
op_ima_obj_attr_get_int32(my_id,"user_id",&user_id);
//printf("user_id = %d\n",user_id);

pkptr = op_pk_get(op_intrpt_strm());
op_pk_nfd_get(pkptr,"seq",&seq);
op_pk_nfd_get(pkptr,"ack",&ack);
op_pk_nfd_get(pkptr,"data",&data);

if(user_id == 0)
{

// printf("seq = %d,ack = %d\n",seq,ack);
// printf("ack_expected = %d,ack = %d,next_frame_to_send = %d\n",ack_expected,ack,next_frame_to_send);
}
//printf("user_id = %d\n",user_id);
if(seq == frame_expected){
//帧只有在被顺序接收的时候才传回网络层
op_pk_send(pkptr,1);
//if(user_id == 0){
// printf("===========================================================\n");
// printf("按顺序接收了一帧,frame_expected = %d\n",frame_expected);
if(user_id == 0)
{
if( (data - previous_data) != 1)
{
printf("丢帧!!!!!!!!!!\n");
}

previous_data = data;
printf("user_id = %d,data = %d\n",user_id,data);
//printf("nbuffered = %d\n",nbuffered);
}
// }
inc(frame_expected);
if(user_id == 0){
//printf("frame_expected = %d\n",frame_expected);
}
} //增加接收者的窗口


while(between(ack_expected,ack,next_frame_to_send)){
//处理ack
nbuffered = nbuffered - 1; //由于响应了一帧,所以减1
//if(user_id == 0){
// printf("减一\n");
// }
stop_timer(ack_expected);
//printf("stop_time %d\n",ack_expected);
inc(ack_expected);
}
//printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");

}
FSM_PROFILE_SECTION_OUT (state3_enter_exec)


/** state ( frame_arrival) exit executives **/
FSM_STATE_EXIT_FORCED (3, " frame_arrival", "Pro5_proc [ frame_arrival exit execs]")




/** state ( frame_arrival) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", " frame_arrival", "wait", "tr_7", "Pro5_proc [ frame_arrival -> wait : default / ]")
/*---------------------------------------------------------*/






/** state (time_out) enter executives **/
FSM_STATE_ENTER_FORCED (4, "time_out", state4_enter_exec, "Pro5_proc [time_out enter execs]")
FSM_PROFILE_SECTION_IN ("Pro5_proc [time_out enter execs]", state4_enter_exec)
{
int inum;
double is ;
int  data ;
Objid my_id;
int user_id;
my_id = op_id_self();
my_id = op_topo_parent(my_id);
op_ima_obj_attr_get_int32(my_id,"user_id",&user_id);
//printf("user_id = %d\n",user_id);

next_frame_to_send = ack_expected; //从这开始重传

if(user_id == 0)
{
// printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
// printf("user_id = %d\n",user_id);
// printf("%d Time Out\n",op_intrpt_code() - 10);

}
for(inum =1;inum <=nbuffered;inum++){
op_pk_nfd_get(buffer[next_frame_to_send],"data",&data);
if(user_id == 0)
{
// printf("next_frame_to_send = %d,frame_expected = %d,data = %d\n",next_frame_to_send,frame_expected,data); 
}
stop_timer(next_frame_to_send);
is = inum;
is= (is-1) * 0.5;
//printf("is = %lf\n",is);
//printf("nbuffered= %d\n",nbuffered);
send_data(next_frame_to_send,frame_expected,0);//重新发送一帧
inc(next_frame_to_send);
}
}
FSM_PROFILE_SECTION_OUT (state4_enter_exec)


/** state (time_out) exit executives **/
FSM_STATE_EXIT_FORCED (4, "time_out", "Pro5_proc [time_out exit execs]")




/** state (time_out) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "time_out", "wait", "tr_9", "Pro5_proc [time_out -> wait : default / ]")
/*---------------------------------------------------------*/






}




FSM_EXIT (0,"Pro5_proc")
}
}








void
_op_Pro5_proc_diag (OP_SIM_CONTEXT_ARG_OPT)
{
/* No Diagnostic Block */
}








void
_op_Pro5_proc_terminate (OP_SIM_CONTEXT_ARG_OPT)
{


FIN_MT (_op_Pro5_proc_terminate ())




/* No Termination Block */


Vos_Poolmem_Dealloc (op_sv_ptr);


FOUT
}




/* Undefine shortcuts to state variables to avoid */
/* syntax error in direct access to fields of */
/* local variable prs_ptr in _op_Pro5_proc_svar function. */
#undef handle_array
#undef next_frame_to_send
#undef ack_expected
#undef frame_expected
#undef r
#undef nbuffered
#undef i
#undef buffer
#undef previous_data
#undef delay


#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE


#define FIN_PREAMBLE_DEC
#define FIN_PREAMBLE_CODE


VosT_Obtype
_op_Pro5_proc_init (int * init_block_ptr)
{
VosT_Obtype obtype = OPC_NIL;
FIN_MT (_op_Pro5_proc_init (init_block_ptr))


obtype = Vos_Define_Object_Prstate ("proc state vars (Pro5_proc)",
sizeof (Pro5_proc_state));
*init_block_ptr = 0;


FRET (obtype)
}


VosT_Address
_op_Pro5_proc_alloc (VosT_Obtype obtype, int init_block)
{
#if !defined (VOSD_NO_FIN)
int _op_block_origin = 0;
#endif
Pro5_proc_state * ptr;
FIN_MT (_op_Pro5_proc_alloc (obtype))


ptr = (Pro5_proc_state *)Vos_Alloc_Object (obtype);
if (ptr != OPC_NIL)
{
ptr->_op_current_block = init_block;
#if defined (OPD_ALLOW_ODB)
ptr->_op_current_state = "Pro5_proc [init enter execs]";
#endif
}
FRET ((VosT_Address)ptr)
}






void
_op_Pro5_proc_svar (void * gen_ptr, const char * var_name, void ** var_p_ptr)
{
Pro5_proc_state *prs_ptr;


FIN_MT (_op_Pro5_proc_svar (gen_ptr, var_name, var_p_ptr))


if (var_name == OPC_NIL)
{
*var_p_ptr = (void *)OPC_NIL;
FOUT
}
prs_ptr = (Pro5_proc_state *)gen_ptr;


if (strcmp ("handle_array" , var_name) == 0)
{
*var_p_ptr = (void *) (prs_ptr->handle_array);
FOUT
}
if (strcmp ("next_frame_to_send" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->next_frame_to_send);
FOUT
}
if (strcmp ("ack_expected" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->ack_expected);
FOUT
}
if (strcmp ("frame_expected" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->frame_expected);
FOUT
}
if (strcmp ("r" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->r);
FOUT
}
if (strcmp ("nbuffered" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->nbuffered);
FOUT
}
if (strcmp ("i" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->i);
FOUT
}
if (strcmp ("buffer" , var_name) == 0)
{
*var_p_ptr = (void *) (prs_ptr->buffer);
FOUT
}
if (strcmp ("previous_data" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->previous_data);
FOUT
}
if (strcmp ("delay" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->delay);
FOUT
}
*var_p_ptr = (void *)OPC_NIL;


FOUT
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值