opnet学习初步——琐碎记录

       近期要做一个简单的无线ad hoc模型,其中路由部分采用OLSR路由协议,MAC部分需要自定义,物理层采用跳频模型。

       首先,搭建一个可以通信的多节点ad hoc网络。此时可以使用modeler自带的wizard。进入方式如下。

       创建出来的节点网络如下所示,可以通过拓扑下拉中的轨迹定义里,设置每个节点的移动形式。


       按照上述设置完成后,需要额外设置每个节点的traffic,才能使通信成功存在。


       另外注意,如果采用jammer模型,需要设置jammer的影响时间间隔,如果设置的过长会导致影响失败。


       在通信成功,并可以找到方法阻止节点通信阶段之后,我进入了很长一个时间的错误学习,方式是阅读代码。这段时间进展极其缓慢。其原因在于不熟悉OPNET的函数集。

       之后,我改变了策略,大致学习了如何在modeler中编程,及常见的函数。

       以下列出个人认为比较重要的函数,及其使用方法。

1.     创建一个指定格式的包

mac_frame_ptr = op_pk_create_fmt(“fddi_mac_fr”);//括号里面是格式的名字,可以通过pk.m文件定义,也可以采取现有的包格式,在declared里面

op_pk_nfd_set(mac_frame_ptr, “svc_class”, svc_class);

op_pk_nfd_set(mac_frame_ptr, “dest_addr”, dest_addr);

op_pk_nfd_set(mac_frame_ptr, “src_addr”, src_addr);

op_pk_nfd_set(mac_frame_ptr, “info”, pdu_ptr);//给该格式的packet的补贴字段赋值

 

2.     获取中断流中的包

pkptr = op_pk_get(op_intrpt_strm());//如果需要获得连续的输入流(包)。可以采用op_strm_pksize()得到队列中包的数量

op_pk_nfd_get(pkptr,”int_value”,&i);//放到i的地址

 

if (op_subq_pk_insert(0,pkptr,OPC_QPOS_HEAD) != OPC_QINS_OK)

{

op_pk_destroy(pkptr);//插入失败则销毁该包 在HELP Symbolic Constants中有描述

}

 

3.     队列函数集——插入与清空

subq_index = op_intrpt_code();//确定哪些子队列正在传输

if(op_subq_empty(subq_index) == OPC_FALSE)

{

pkptr = op_subq_pk_remove(subq_index,OPQ_QPOS_HEAD);

op_pk_send_quiet(pkptr,subq_index);//使用安静模式传输

}

4.     标识、拓扑和内部模型访问函数集

own_id = op_id_self();//返回类型是objid标识本进程处理器或队列的对象ID

op_ima_obj_attr_get(own_id, “service_rate”,&service_rate);//获取对象的属性,其中service rate需要预先定义

ppid = op_topo_parent(own_id);//得到特定对象父对象的对象id

op_ima_obj_attr_get(ppid, “service_rate”,&service_rate);//获取对象的属性

同理还有子id op_topo_child()

5.     中断函数集(很关键,描述4个例子)

a.     op_intrpt_schedule_self()

pkptr = op_subq_pk_access(0,OPC_QPOS_HEAD);

pk_len = op_pk_total_size_get(pkptr);

pk_svc_time = pk_len/service_rate;

op_intrpt_schedule_self(op_sim_time()+pk_svc_time, 0);

server_busy = 1;

在特定时间里面,为激活进程调度一个中断;常见的是等待ACK,此时需要采用op_ev_cancel(evh)取消进程

b.     op_intrpt_type()

type = op_intrpt_type();//获取中断类型

switch(type)

{

case(OPC_INTRPT_STRM):

break;

case(OPC_INTRPT_SELF):

break;

case(OPC_INTRPT_STAT)://一般用在MAC层判断无线信道是否空闲

break;

default:

}

c.     op_intrpt_code()返回值是int,和当前中断相关的数字代码,便于从中断中读取用户自定义的代码可以获得该中断的目的,当有几个不同目的的中断存在时,该值非常必要,例如存在多个超时自中断。

If (op_intrpt_code() == X25C_T13)

 

d.     op_intrpt_strm() 返回值是int类型,当前中断的流索引,当一个包通过op_pk_deliver()或者op_pk_send()转入,或者通过op_strm_access()读取时,该值被明确定义

if (op_intrpt_type() == OPC_INTRPT_STRM && op_intrpt_strm() == LOW_LAYER_INPUT_STREAM)

{

eth_mac_phys_pk_accept();

}

else if (op_intrpt_type() == OPC_INTRPT_STRM && op_intrpt_strm() == HIGH_LAYER_INPUT_STREAM)

{

eth_mac_llc_pk_accept();

 

}

6.     统计量函数集
if  (conn_id < FRMSC_PVC_COMM_STAT_COUNT):

frms_ete_del_lhandle = op_stat_reg(“Frame Relay PVC. Delay(sec)”, conn_id, OPC_STAT_LOCAL);//参数一是统计量,参数二是索引号,参数三是局部或全局索引

 

7.     分布函数集

主要有两个函数

op_dist_load()返回值是一个指向分布函数的指针

job_type_dist = op_dist_load(“uniform_int”,1,job_type_range)

if (job_type_dist == OPC_NIL)://抛出错误

jsd_gen_error(“unable to load job type distribution”);

   op_dist_outcome()通过调用获得分布结果,返回值是根据特定分布得到的随机值

   next_pk_arrvl_time = op_sim_time() + op_dist_outcome(int_arrival_distptr);

   if (next_pk_arrvl_time < gen_end_time || gen_end_time == FRMSC_ARRL_END_OF_SIM)

   {

       op_intrpt_schedule_self(next_pk_arrvl_time,FRMSC_FR_APPL_TRAF_GEN);

}

8.     事件与仿真函数集

op_ev_cancel()

this_event = op_ev_current();

next_event = op_ev_next_local(this_event);

while (op_ev_valid(next_event))

{

If (op_ev_type(next_event) == OPC_INTRPT_SELF && op_ev_code(next_event) == RETRANS_TIMER)

{

retrains_timer = next_event;

next_event = op_ev_next_local(retrains_timer);

op_ev_cancel(retrains_timer);

}

else

next_event = op_ev_next_local(next_event);

}

9.     接口函数集

for (i = send_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值