您的位置:首页 > 编程语言

excoax_net学习笔记之eth_mac_v2 -----INIT 出口代码

2012-09-09 11:16 465 查看
初学opnet 如理解有误,欢迎指正

INIT 出口代码 出口代码有点长,不要被吓到了


/* Obtain the address assigned to this node. */

if (op_ima_obj_attr_get (mac_attr_objid, "Address", &my_32bit_address) //op_ima_obj_attr_get(objid,attr_name,value_ptr) 从指定的对象objid中获取属性attr_name放到value_ptr中 value_ptr是void*型 返回值为compcode

== OPC_COMPCODE_FAILURE)

{

eth_mac_error ("Unable to read station address attribute.", OPC_NIL, OPC_NIL);

}

/* Perform auto-addressing for the MAC address dynamically addresses·, if auto-assigned, the address resolution function also detects duplicate */

/* static assignments. By default each address is */

/* considered as being a valid destination unless it is */

/* explicitly set. */

oms_aa_address_resolve (oms_aa_handle, mac_attr_objid, &my_32bit_address);//

Creates a new, unique address (if theaddress is auto-assigned), or verifies that theaddress
is unique (if the address is explicitly assigned). 所以有检测重复分配的功能

/* Initialize and export the frame-waiting variable used */ 初始化并导出帧等待变量

/* by deference process in computing deference intervals. */

frame_waiting = 0.0;

op_stat_write (frame_handle, frame_waiting);

/* Obtain the node's object id. */

own_node_objid = op_topo_parent (my_objid); 获得节点id

/* Obtain the process's process handle. */

own_prohandle = op_pro_self (); //获得进程句柄

/* Obtain the name of the process. */

op_ima_obj_attr_get (my_objid, "process model", proc_model_name);

/* Register this Ethernet MAC process in the model-wide registry. */

own_process_record_handle = (OmsT_Pr_Handle) oms_pr_process_register (own_node_objid, my_objid, 获得记录进程注册信息的句柄

own_prohandle, proc_model_name);

/* Register the protocol attribute and mac type info of this */

/* process into the model-wide registry. */

oms_pr_attr_set (own_process_record_handle, "protocol", OMSC_PR_STRING, "mac", OPC_NIL); 在句柄中注册协议信息 name type value ...OPNIL

oms_pr_attr_set (own_process_record_handle, "mac_type", OMSC_PR_STRING, "eth", OPC_NIL); /*两句可以合并为一句 oms_pr_attr_set (own_process_record_handle, "protocol", OMSC_PR_STRING, "mac", "mac_type", OMSC_PR_STRING, "eth",OPC_NIL);*/

/* Determine object identifier of transmitter connecting */

/* the MAC layer to the bus. This Objid is needed to abort */

/* collided transmissions in the "COLLISION" state. */

tx_objid = op_topo_assoc (op_id_self (), OPC_TOPO_ASSOC_OUT,

OPC_OBJTYPE_BUTX, LOW_LAYER_OUTPUT_STREAM); //获得与进程id的出线相连的id 即发射机的id

if (tx_objid == OPC_OBJID_INVALID)

{

eth_mac_error ("Unable to get Objid of transmitter module.",

"Node model is probably incorrect; make sure that",

"eth_mac connects to a bus transmitter through output stream 0.");

}

/* Get the compound attribute tx id */获得发射机id的综合属性

op_ima_obj_attr_get (tx_objid, "channel", &tx_comp_attr_objid); 此处将发射机id的channel属性填入tx_comp_attr_objid

if (tx_comp_attr_objid == OPC_OBJID_INVALID)

{

eth_mac_error("Unable to get Objid of transmitter compound attribute",OPC_NIL,OPC_NIL);

}

/* determine the bitrate used by the transmitter's channel */确定发射机信道的比特率

tx_channel_objid = op_topo_child(tx_comp_attr_objid, OPC_OBJTYPE_BUTXCH, 0); // op_topo_child(parent_objid,child_type,child_index)

if (tx_channel_objid == OPC_OBJID_INVALID) {

eth_mac_error ("Unable to get Objid of transmitter channel.",

OPC_NIL, OPC_NIL);

}

/* Determine the bitrate used by the transmitter's channel. */

if (op_ima_obj_attr_get (tx_channel_objid, "data rate", &bit_rate)//这种if语句 当条件不满足时,前半句也已经执行了

== OPC_COMPCODE_FAILURE)

{

eth_mac_error ("Unable to get data rate from transmitter channel.",

OPC_NIL, OPC_NIL);

}

/* Create an interface control information (ICI) structure for */创建ICI与上层通信

/* communication of parameters with the higher layer (LLC). */

llc_iciptr = op_ici_create ("eth_mac_ind"); 返回ici* 指向ICI函数

if (llc_iciptr == OPC_NIL)

{

eth_mac_error ("Unable to create ICI for communication with LLC.",

OPC_NIL, OPC_NIL);

}

/* Get the promiscuous mode (if all packets will be accepted) */

op_ima_obj_attr_get(mac_attr_objid, "Promiscuous Mode", &promis); 获取属性 Promiscuous Mode

/* Check if this ethernet MAC is for a port in a bridge/switch */
检查以太网mac是否支持端口的网桥/交换机节点

/* node. In this case, the MAC will not participate in any */

/* encapsulation/decapsulation of frames, nor will it record */

/* any statistics. */

proc_record_handle_list_ptr = op_prg_list_create ();

oms_pr_process_discover (OPC_OBJID_INVALID, proc_record_handle_list_ptr, //在进程注册表中寻找符合特定条件的进程

"node objid", OMSC_PR_OBJID, own_node_objid,

"protocol", OMSC_PR_STRING, "bridge",

OPC_NIL);

/* If the surrounding node is a bridge/switch node, the list */

/* will contain an element to indicate that another process in */

/* this node has registered itself as a bridge/switch. */

if (op_prg_list_size (proc_record_handle_list_ptr) == 1)

{

mac_port_of_a_bridge_switch_node = OPC_TRUE;

}

/* Deallocate process registry information. */

while (op_prg_list_size (proc_record_handle_list_ptr))

op_prg_list_remove (proc_record_handle_list_ptr, OPC_LISTPOS_HEAD);

op_prg_mem_free (proc_record_handle_list_ptr);

/************************************************************************/

/* This process can be simultaneously used to send/receive packets both */这个进程可以同时使用IP和IPX收发包

由于IP和IPX作为单独的协议栈实现,所以每个网络层有一对与周围模块相关联的数据流。使用OMS进程注册表来查看在这个节点中使用了一种还是两种协议栈。根据每个网络层的实现,确定输入输出的包流索引

/* from IP and IPX. Since IP and IPX are implemented as separate stacks */

/* each network layer can have a pair of streams associated with the */

/* surrounding module. Use the OMS Process Registry to find out if both */

/* or just one of the two are present in this node. For each network */

/* layer implementation that is present, determine the incoming and */

/* outgoing packet stream index. */

/************************************************************************/

/************************************************************************/

/* Find out if the IPX stack is present. */ 寻找使用IPX的节点

/************************************************************************/

/* Create an instance of the List data structure. */

proc_record_handle_list_ptr = op_prg_list_create ();

/* Discover all processes that are neighbors of the parent module and */

/* that have registered a value of 'ipx_bcast_intf' for the value of */

/* the 'protocol' attribute. */

oms_pr_process_discover (my_objid, proc_record_handle_list_ptr, 寻找范围:当前节点的父节点内

"node objid", OMSC_PR_OBJID, (op_id_parent (my_objid)),

"protocol", OMSC_PR_STRING, "ipx_bcast_intf",

OPC_NIL);

/* For each ethernet data link implementation, there should be just one */

/* neighbor module hosting the 'ipx_bcast_intf' process. If this is */

/* true then obtain the object ID of that neighbor module. */

if (op_prg_list_size (proc_record_handle_list_ptr) == 1) 如果找到了符合IPX的节点

{

/* Else, access the single process record handle. */

proc_record_handle = (OmsT_Pr_Handle) op_prg_list_remove (

proc_record_handle_list_ptr, OPC_LISTPOS_HEAD);

/* Obtain the value of the 'protocol' attribute published by the IPX*/

/* process. */

if (oms_pr_attr_get (proc_record_handle, "module objid" 获取节点id,

OMSC_PR_OBJID, &mod_objid) == OPC_COMPCODE_FAILURE)

{

eth_mac_error (

"Failed to get value of 'module objid' attr. from OMS PR.",

OPC_NIL, OPC_NIL);

}

/* Determine the input and output stream indices to be used when */

/* sending/receiving packets from the IPX network layer. */确定输入输出流索引

if (oms_tan_neighbor_streams_find (

my_objid, mod_objid, &strm_from_ipx, &strm_to_ipx) == 需用到当前节点id和符合条件的节点id

OPC_COMPCODE_FAILURE)

{

eth_mac_error (

"Failed to determine the I/P and O/P streams from and to the IPX",

"network layer implementation.", OPC_NIL);

}

}

/* If there is no neighbor module hosting the ipx_bcast_intf process */

/* set the values of the I/P and O/P stream state vars. to OPC_INT_UNDEF*/

else if (op_prg_list_size (proc_record_handle_list_ptr) == 0) 如果找不到符合的节点

{

strm_to_ipx = OPC_INT_UNDEF; 将输入输出流索引号设为默认

strm_from_ipx = OPC_INT_UNDEF;

}

/* If more than one neighbor module was found then flag the error and */

/* exit the simulation. */

else if (op_prg_list_size (proc_record_handle_list_ptr) > 1)如果找到符合的节点多于一个

{

eth_mac_error ( 报错

"Found more than one IPX Broadcast Intf. process registered in OMS PR.",

OPC_NIL, OPC_NIL);

}

/* Deallocate process registry information. Note that we do not */

/* deallocate the memory referenced by the members of the process */

/* record handle list. This is because the members of this list are */

/* pointers to memory ALSO REFERENCED IN THE GLOBAL PROCESS REGISTRY*/

while (op_prg_list_size (proc_record_handle_list_ptr)) 释放链表

op_prg_list_remove (proc_record_handle_list_ptr, OPC_LISTPOS_HEAD);

op_prg_mem_free (proc_record_handle_list_ptr);释放链表内存

/************************************************************************/

/* Find out if the IP stack is present. */ 寻找使用IP的节点 (步骤同上)

/************************************************************************/

/* Create an instance of the List data structure. */

proc_record_handle_list_ptr = op_prg_list_create ();

/* Discover all processes that are neighbors of the parent module and */

/* that have registered a value of 'arp' for the value of the 'protocol'*/

/* attribute. */

oms_pr_process_discover (my_objid, proc_record_handle_list_ptr,

"node objid", OMSC_PR_OBJID, (op_id_parent (my_objid)),

"protocol", OMSC_PR_STRING, "arp",

OPC_NIL);

/* For each ethernet data link implementation, there should be just one */

/* neighbor module hosting the 'arp' process. If this is true then */

/* obtain the object ID of that neighbor module. */

if (op_prg_list_size (proc_record_handle_list_ptr) == 1)

{

/* Else, access the single process record handle. */

proc_record_handle = (OmsT_Pr_Handle) op_prg_list_remove (

proc_record_handle_list_ptr, OPC_LISTPOS_HEAD);

/* Obtain the value of the 'module objid' attribute published by */

/* the arp process. */

if (oms_pr_attr_get (proc_record_handle, "module objid",

OMSC_PR_OBJID, &mod_objid) == OPC_COMPCODE_FAILURE)

{

eth_mac_error (

"Failed to get value of 'module objid' attr. from OMS PR.",

OPC_NIL, OPC_NIL);

}

/* Determine the input and output stream indices to be used when */

/* sending/receiving packets from the IP network layer. */

if (oms_tan_neighbor_streams_find (

my_objid, mod_objid, &strm_from_ip, &strm_to_ip) ==

OPC_COMPCODE_FAILURE)

{

eth_mac_error (

"Failed to determine the I/P and O/P streams from and to the IP",

"network layer implementation.", OPC_NIL);

}

}

/* If there is no neighbor module hosting the ipx_bcast_intf process */

/* set the values of the I/P and O/P stream state vars. to OPC_INT_UNDEF*/

else if (op_prg_list_size (proc_record_handle_list_ptr) == 0)

{

strm_to_ip = OPC_INT_UNDEF;

strm_from_ip = OPC_INT_UNDEF;

}

/* If more than one neighbor module was found then flag the error and */

/* exit the simulation. */

else if (op_prg_list_size (proc_record_handle_list_ptr) > 1)

{

eth_mac_error (

"Found more than one IP Addr. Res. Protocol process registered in OMS PR.",

OPC_NIL, OPC_NIL);

}

/* Deallocate process registry information. Note that we do not */

/* deallocate the memory referenced by the members of the process */

/* record handle list. This is because the members of this list are */

/* pointers to memory ALSO REFERENCED IN THE GLOBAL PROCESS REGISTRY*/

while (op_prg_list_size (proc_record_handle_list_ptr))

op_prg_list_remove (proc_record_handle_list_ptr, OPC_LISTPOS_HEAD);

op_prg_mem_free (proc_record_handle_list_ptr);

/* Schedule a self interrupt to move from the "start" state. */

/* This additional state is necessary to confirm the final MAC */

/* address if it is dynamically assigned (auto assigned). */

op_intrpt_schedule_self (op_sim_time (), 0); 产生一个自中断
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: