選擇性重傳協議(基於Opnet)

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






/* This variable carries the header into the object file */
const char Pro6_pr_c [] = "MIL_3_Tfile_Hdr_ 145A 30A modeler 7 500E3FA1 500E3FA1 1 AlchemyStar-PC AlchemyStar 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 63
#define NR_BUFS ((MAX_SEQ + 1)/2)
#include "protocol.h"
#define DATA 0
#define ACK 1
#define NAK 2
#define wait_for_init (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() == 0)
#define network_ready_intrpt (op_intrpt_type() == OPC_INTRPT_STRM && op_intrpt_strm() == 0)
#define frame_arrival_intrpt (op_intrpt_type() == OPC_INTRPT_STRM && op_intrpt_strm()== 1)
#define ACK_TIMER 5
#define ack_time_intrpt (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() ==  5)
#define time_out_intrpt (op_intrpt_type() == OPC_INTRPT_SELF && (op_intrpt_code() >=10))




/* 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 */
Boolean                 no_nak                                          ;
int                     oldest_frame                                    ;
Evhandle               handle_array[NR_BUFS]                           ;
int                     ack_expected                                    ; /* 接收窗口的下部 */
int                     next_frame_to_send                              ; /* 發送窗口的上部+1 */
int                     frame_expected                                  ; /* 接收窗口的下部 */
int                     too_far                                         ; /* 接收窗口的上部+1 */
int                     i                                               ; /* buffer池的索引 */
int                     r                                               ; /* scratch variable */
Packet *               out_buf[NR_BUFS]                                ; /* 輸出流的buffers */
Packet *               in_buf[NR_BUFS]                                 ; /* 輸入流的buffers */
Boolean                 arrived[NR_BUFS]                                ; /* 用來指明該緩衝區是滿的還是空的 */
int                     nbuffered                                       ; /* 當前由多少輸出緩衝在使用 */
Evhandle               ack_timer                                       ; /* 定時器事件 */
int                     previous_data                                   ;
} Pro6_state;


#define no_nak                   op_sv_ptr->no_nak
#define oldest_frame             op_sv_ptr->oldest_frame
#define handle_array             op_sv_ptr->handle_array
#define ack_expected             op_sv_ptr->ack_expected
#define next_frame_to_send       op_sv_ptr->next_frame_to_send
#define frame_expected           op_sv_ptr->frame_expected
#define too_far                 op_sv_ptr->too_far
#define i                       op_sv_ptr->i
#define r                       op_sv_ptr->r
#define out_buf                 op_sv_ptr->out_buf
#define in_buf                   op_sv_ptr->in_buf
#define arrived                 op_sv_ptr->arrived
#define nbuffered               op_sv_ptr->nbuffered
#define ack_timer               op_sv_ptr->ack_timer
#define previous_data           op_sv_ptr->previous_data


/* 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 Pro6_state *op_sv_ptr;
#define FIN_PREAMBLE_CODE \
op_sv_ptr = ((Pro6_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 <= NR_BUFS + 1)
{
op_ev_cancel_if_pending(handle_array[(seq % NR_BUFS)]);
handle_array[(seq % NR_BUFS)] = op_intrpt_schedule_self(op_sim_time() + 5.0 ,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 <= NR_BUFS + 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 start_ack_timer()
{
FIN(start_ack_timer());
//重置
op_ev_cancel_if_pending(ack_timer);
ack_timer = op_intrpt_schedule_self(op_sim_time() + 0.7,ACK_TIMER); //定義code = 5爲自中斷
FOUT;
}




static void stop_ack_timer()
{
FIN(stop_ack_timer());
op_ev_cancel_if_pending(ack_timer);
FOUT;
}
static void send_frame(int fk,int frame_nr,int frame_expected_r,Packet** buffer)
{
//構造併發送一個數data,ack或者是nak幀
Packet* pkptr;
int seq;
int ack;

int data1;




Objid my_id;
int user_id;

FIN(send_frame(int fk,int frame_nr,int frame_expected_r,Packet** buffer));

my_id = op_id_self();
my_id = op_topo_parent(my_id);
op_ima_obj_attr_get_int32(my_id,"SCID",&user_id);

seq = frame_nr;
ack = (frame_expected_r + MAX_SEQ)%(MAX_SEQ + 1);
pkptr = op_pk_create_fmt("Pro6");
op_pk_nfd_set_int32(pkptr,"frame_kind",fk);

if(fk == DATA){
pkptr = op_pk_copy(buffer[frame_nr % NR_BUFS]);
}
op_pk_nfd_set(pkptr,"seq",seq);
op_pk_nfd_set(pkptr,"ack",ack);
op_pk_nfd_get(pkptr,"data",&data1);
// if(user_id == 1){
// printf("LLLLLLLLLLLLLLLLL kind = %d,seq = %d,data = %d\n",fk,seq,data1);
// }
if(fk == NAK){
no_nak = false;
}
op_pk_send(pkptr,0);
if(fk == DATA){
start_timer(frame_nr);
}
stop_ack_timer(); //不再需要單獨的ack幀了,捎帶確認了


FOUT;
}



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

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 Pro6 (OP_SIM_CONTEXT_ARG_OPT);
VosT_Obtype _op_Pro6_init (int * init_block_ptr);
void _op_Pro6_diag (OP_SIM_CONTEXT_ARG_OPT);
void _op_Pro6_terminate (OP_SIM_CONTEXT_ARG_OPT);
VosT_Address _op_Pro6_alloc (VosT_Obtype, int);
void _op_Pro6_svar (void *, const char *, void **);




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








/* Process model interrupt handling procedure */




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


{




FSM_ENTER ("Pro6")


FSM_BLOCK_SWITCH
{
/*---------------------------------------------------------*/
/** state (init) enter executives **/
FSM_STATE_ENTER_UNFORCED (0, "init", state0_enter_exec, "Pro6 [init enter execs]")
FSM_PROFILE_SECTION_IN ("Pro6 [init enter execs]", state0_enter_exec)
{
no_nak = true;
oldest_frame = MAX_SEQ + 1;

ack_expected = 0;
next_frame_to_send = 0;
frame_expected = 0;
too_far = NR_BUFS;
nbuffered = 0;
for(i=0;i<NR_BUFS;i++){
arrived[i] = false; //當前緩衝全爲空
}

op_intrpt_schedule_self(op_sim_time()+3,0); //wait for init intrpt
}
FSM_PROFILE_SECTION_OUT (state0_enter_exec)


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




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




/** state (init) transition processing **/
FSM_PROFILE_SECTION_IN ("Pro6 [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_2", "Pro6 [init -> wait : wait_for_init / ]")
FSM_CASE_TRANSIT (1, 0, state0_enter_exec, ;, "default", "", "init", "init", "tr_0", "Pro6 [init -> init : default / ]")
}
/*---------------------------------------------------------*/






/** state (wait) enter executives **/
FSM_STATE_ENTER_UNFORCED (1, "wait", state1_enter_exec, "Pro6 [wait enter execs]")
FSM_PROFILE_SECTION_IN ("Pro6 [wait enter execs]", state1_enter_exec)
{
if(nbuffered < NR_BUFS)
{
enable_network_layer();
}
}
FSM_PROFILE_SECTION_OUT (state1_enter_exec)


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




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




/** state (wait) transition processing **/
FSM_PROFILE_SECTION_IN ("Pro6 [wait trans conditions]", state1_trans_conds)
FSM_INIT_COND (network_ready_intrpt)
FSM_TEST_COND (frame_arrival_intrpt)
FSM_TEST_COND (ack_time_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_ready_intrpt", "", "wait", "network_layer_ready", "tr_3", "Pro6 [wait -> network_layer_ready : network_ready_intrpt / ]")
FSM_CASE_TRANSIT (1, 3, state3_enter_exec, ;, "frame_arrival_intrpt", "", "wait", "frame_arrival", "tr_9", "Pro6 [wait -> frame_arrival : frame_arrival_intrpt / ]")
FSM_CASE_TRANSIT (2, 4, state4_enter_exec, ;, "ack_time_intrpt", "", "wait", "ack_timeout", "tr_22", "Pro6 [wait -> ack_timeout : ack_time_intrpt / ]")
FSM_CASE_TRANSIT (3, 5, state5_enter_exec, ;, "time_out_intrpt", "", "wait", "time_out", "tr_26", "Pro6 [wait -> time_out : time_out_intrpt / ]")
FSM_CASE_TRANSIT (4, 1, state1_enter_exec, ;, "default", "", "wait", "wait", "tr_19", "Pro6 [wait -> wait : default / ]")
}
/*---------------------------------------------------------*/






/** state (network_layer_ready) enter executives **/
FSM_STATE_ENTER_FORCED (2, "network_layer_ready", state2_enter_exec, "Pro6 [network_layer_ready enter execs]")
FSM_PROFILE_SECTION_IN ("Pro6 [network_layer_ready enter execs]", state2_enter_exec)
{
//接收,保存和發送一個新的幀
Packet* pkptr;
Packet* pk_copy;

nbuffered = nbuffered + 1; //拓寬窗口

//獲取這個幀
pkptr = op_pk_get(op_intrpt_strm());


pk_copy = op_pk_copy(pkptr);
out_buf[next_frame_to_send % NR_BUFS] = pk_copy; //將新的幀保存起來
send_frame(DATA,next_frame_to_send,frame_expected,out_buf); //發送當前從網絡層得到的幀


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", "Pro6 [network_layer_ready exit execs]")




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






/** state (frame_arrival) enter executives **/
FSM_STATE_ENTER_FORCED (3, "frame_arrival", state3_enter_exec, "Pro6 [frame_arrival enter execs]")
FSM_PROFILE_SECTION_IN ("Pro6 [frame_arrival enter execs]", state3_enter_exec)
{
//一個數據或者控制幀到達了
Packet* pkptr;
Packet* pk_copy;
Packet* pk_send;
int seq;
int data1;
int ack;
int kind;
int Service_number;


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,"SCID",&user_id);

pkptr = op_pk_get(op_intrpt_strm()); //從物理層接受幀 
pk_copy = op_pk_copy(pkptr);
op_pk_nfd_get(pkptr,"seq",&seq);
op_pk_nfd_get(pkptr,"ack",&ack);
op_pk_nfd_get(pkptr,"data",&data1);
op_pk_nfd_get(pkptr,"frame_kind",&kind);
op_pk_nfd_get(pkptr,"Service",&Service_number);
if(user_id == 0){
//printf("seq = %d,data1 = %d\n",seq,data1);
}
if(kind == DATA){
//一個沒有毀壞的幀到來了
if((seq != frame_expected) && no_nak){
send_frame(NAK,0,frame_expected,out_buf);
}
else{
start_ack_timer();
}
if(between(frame_expected,seq,too_far) && (arrived[seq % NR_BUFS] == false)){
//幀可能以任何順序被接收
arrived[seq % NR_BUFS] = true; //此緩衝區滿了
in_buf[seq % NR_BUFS] = pk_copy; //將數據放入緩衝區中
while(arrived[frame_expected % NR_BUFS]){
//傳遞幀和增加窗口
pk_send = op_pk_copy(in_buf[frame_expected % NR_BUFS]);
op_pk_nfd_get(pk_send,"data",&data1) ;
op_pk_send(pk_send,1);
arrived[frame_expected % NR_BUFS] = false;

if(user_id == 0){
if(data1 - previous_data != 1){
printf("丟幀\n");
}
//if(Service_number != 0 && Service_number !=1){
printf("Service = %d,current_time = %lf,data  = %d,frame_expected = %d!!!!!!!!!!!!!!!\n",Service_number,op_sim_time(),data1,frame_expected);
//}
}
previous_data = data1;
no_nak = true;

inc(frame_expected); //增加接受窗口的下邊緣
if(user_id == 0){
//printf(">>>frame_expected = %d\n",frame_expected);
}
inc(too_far) ;//增加接收窗口的上邊緣

}
start_ack_timer() ; //看看是否一個單獨的ack是需要的,表明當前幀被接受了
}

}

if((kind == NAK) && between(ack_expected,(ack+1)%(MAX_SEQ + 1),next_frame_to_send))
{
//上面的判斷表明kind == NAK同時ack的這一幀已經被髮送出去了
if(user_id == 0){
//printf("接受到了NAK,現在重發seq = %d,ack = %d\n",(ack+1)%(MAX_SEQ + 1),frame_expected);
}
send_frame(DATA,(ack + 1)%(MAX_SEQ + 1),frame_expected,out_buf);
}

if(user_id == 0){
//printf("user == 1,ack = %d,ack_expected = %d\n",ack,ack_expected);
}

while(between(ack_expected,ack,next_frame_to_send)){
nbuffered = nbuffered - 1; //處理piggybacked ack
//printf(">>>>>>>>>>>>ack_expected = %d>>>>>>>>>>>>>>>>\n",ack_expected);
if(user_id == 1){
// printf("user == 1,ack = %d,ack_expected = %d+++++\n",ack_expected);
}
stop_timer((ack_expected % NR_BUFS));
if(user_id == 1){
//printf("Kill timer %d\n",(ack_expected % NR_BUFS));
}
if(user_id == 0){
//printf("killer_timer = %d\n",ack_expected);
}
inc(ack_expected) ; //增加發送者窗口的下邊緣
}




}
FSM_PROFILE_SECTION_OUT (state3_enter_exec)


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




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






/** state (ack_timeout) enter executives **/
FSM_STATE_ENTER_FORCED (4, "ack_timeout", state4_enter_exec, "Pro6 [ack_timeout enter execs]")
FSM_PROFILE_SECTION_IN ("Pro6 [ack_timeout enter execs]", state4_enter_exec)
{
//printf("ack time out,frame_expected = %d\n",frame_expected);
send_frame(ACK,0,frame_expected,out_buf);
}
FSM_PROFILE_SECTION_OUT (state4_enter_exec)


/** state (ack_timeout) exit executives **/
FSM_STATE_EXIT_FORCED (4, "ack_timeout", "Pro6 [ack_timeout exit execs]")




/** state (ack_timeout) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "ack_timeout", "wait", "tr_18", "Pro6 [ack_timeout -> wait : default / ]")
/*---------------------------------------------------------*/






/** state (time_out) enter executives **/
FSM_STATE_ENTER_FORCED (5, "time_out", state5_enter_exec, "Pro6 [time_out enter execs]")
FSM_PROFILE_SECTION_IN ("Pro6 [time_out enter execs]", state5_enter_exec)
{
int data1;
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,"SCID",&user_id);

op_pk_nfd_get_int32(out_buf[((op_intrpt_code() - 10)%NR_BUFS)],"data",&data1);
if(user_id == 1){
//printf("time out,current_time = %lf,準備重傳的seq = %d,data1 = %d\n",op_sim_time(),op_intrpt_code() - 10,data1);
}

send_frame(DATA,op_intrpt_code() - 10,frame_expected,out_buf);


}
FSM_PROFILE_SECTION_OUT (state5_enter_exec)


/** state (time_out) exit executives **/
FSM_STATE_EXIT_FORCED (5, "time_out", "Pro6 [time_out exit execs]")




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






}




FSM_EXIT (0,"Pro6")
}
}








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








void
_op_Pro6_terminate (OP_SIM_CONTEXT_ARG_OPT)
{


FIN_MT (_op_Pro6_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_Pro6_svar function. */
#undef no_nak
#undef oldest_frame
#undef handle_array
#undef ack_expected
#undef next_frame_to_send
#undef frame_expected
#undef too_far
#undef i
#undef r
#undef out_buf
#undef in_buf
#undef arrived
#undef nbuffered
#undef ack_timer
#undef previous_data


#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE


#define FIN_PREAMBLE_DEC
#define FIN_PREAMBLE_CODE


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


obtype = Vos_Define_Object_Prstate ("proc state vars (Pro6)",
sizeof (Pro6_state));
*init_block_ptr = 0;


FRET (obtype)
}


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


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






void
_op_Pro6_svar (void * gen_ptr, const char * var_name, void ** var_p_ptr)
{
Pro6_state *prs_ptr;


FIN_MT (_op_Pro6_svar (gen_ptr, var_name, var_p_ptr))


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


if (strcmp ("no_nak" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->no_nak);
FOUT
}
if (strcmp ("oldest_frame" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->oldest_frame);
FOUT
}
if (strcmp ("handle_array" , var_name) == 0)
{
*var_p_ptr = (void *) (prs_ptr->handle_array);
FOUT
}
if (strcmp ("ack_expected" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->ack_expected);
FOUT
}
if (strcmp ("next_frame_to_send" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->next_frame_to_send);
FOUT
}
if (strcmp ("frame_expected" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->frame_expected);
FOUT
}
if (strcmp ("too_far" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->too_far);
FOUT
}
if (strcmp ("i" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->i);
FOUT
}
if (strcmp ("r" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->r);
FOUT
}
if (strcmp ("out_buf" , var_name) == 0)
{
*var_p_ptr = (void *) (prs_ptr->out_buf);
FOUT
}
if (strcmp ("in_buf" , var_name) == 0)
{
*var_p_ptr = (void *) (prs_ptr->in_buf);
FOUT
}
if (strcmp ("arrived" , var_name) == 0)
{
*var_p_ptr = (void *) (prs_ptr->arrived);
FOUT
}
if (strcmp ("nbuffered" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->nbuffered);
FOUT
}
if (strcmp ("ack_timer" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->ack_timer);
FOUT
}
if (strcmp ("previous_data" , var_name) == 0)
{
*var_p_ptr = (void *) (&prs_ptr->previous_data);
FOUT
}
*var_p_ptr = (void *)OPC_NIL;


FOUT
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章