logo资料库

OPNET中802.11信道模型.docx

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
图为 802.11 协议的信道进程模型,通过信道进程模型可以得到全局统计量 SINR 进程模型有两个非强制状态和三个强制状态 头文件中定义了转移条件和中断结构 #include "WLAN_def.h" #include "WLAN_data.h" #include "WLAN_func.h" 转移条件 #define SYS_INIT == INTRPT_SYS_INIT)) #define PHY_TXSTART == INTRPT_PHY_TXSTART_REQUEST)) 中断方式为远程中断 ((op_intrpt_type() == OPC_INTRPT_MCAST) && (op_intrpt_code() 中断方式为多路广播中断中断号是系统初始化 ((op_intrpt_type() == OPC_INTRPT_REMOTE) && (op_intrpt_code() #define PHY_TXEND == INTRPT_PHY_TXEND)) ((op_intrpt_type() == OPC_INTRPT_SELF) && (op_intrpt_code() 自中断 typedef enum INTRPT_RADIO_CHANNEL_T { INTRPT_PHY_TXEND } INTRPT_RADIO_CHANNEL_T; 函数声明 static double get_MPDU_power(int, MPDU_T *); 获得 MPDU 的功率 static void channel_status_refresh(void); static void MPDU_sinr_segment_refresh(void); static void MPDU_sinr_calculate(MPDU_T *); 更新 MPDU 的 SINR 字段 计算 MPDU 的 SINR 刷新信道(将功率值写入统计量)
函数定义文件 static double 获得 MPDU 的功率 get_MPDU_power(int lvi_node_index, MPDU_T *lvp_MPDU) { int lvi_frequency_band; 频率范围 double lvd_MPDU_power; MPDU 功率 double lvd_pathloss; 路损 FIN(get_MPDU_power()); /* this node is an AP */ 接入点 if (lvi_node_index < gvi_AP_number) { lvi_frequency_band = gvo_AP_property[lvi_node_index].frequency_band; } /* otherwise, this node is an STA */ 移动站 else { lvi_frequency_band = gvo_AP_property[gvo_STA_property[lvi_node_index - gvi_AP_number].serving_AP].frequency_band; } /* cochannel signal */ 同信道信号 if (lvp_MPDU->frequency_band == lvi_frequency_band) { lvd_MPDU_power = lvp_MPDU->power; lvd_pathloss = gvo_pathloss_matrix[lvp_MPDU->source_node_index][lvi_node_index]; // linear value // dB value lvd_pathloss = pow(10.0, lvd_pathloss/10.0); FRET(lvd_MPDU_power / lvd_pathloss); } /* otherwise, non-cochannel signal */ { FRET(0.0); 返回 0 } } static void 信道状态更新 channel_status_refresh() { int lvi_AP_index; 接入点索引 int lvi_STA_index; 移动站索引
int lvi_node_index; 节点索引 int lvi_MPDU_index; MPDU 索引 int lvi_MPDU_number; MPDU 数量 MPDU_T *lvp_MPDU; MPDU 的指针 double lvd_sum_power double lvd_sum_power_dBm; ; FIN(channel_status_refresh()); lvi_MPDU_number = op_prg_list_size(gvlist_radio_channel); 获得信道中 MPDU 的数量 遍历所有的接入点 for (lvi_AP_index = 0; lvi_AP_index < gvi_AP_number; lvi_AP_index++) { lvi_node_index = lvi_AP_index; lvd_sum_power = 0.0; 遍历信道中所有的 MPDU for (lvi_MPDU_index = 0; lvi_MPDU_index < lvi_MPDU_number; lvi_MPDU_index++) { (MPDU_T lvi_MPDU_index); 获取信道中的某位置 MPDU lvp_MPDU = *)op_prg_list_access(gvlist_radio_channel, lvd_sum_power += get_MPDU_power(lvi_node_index, lvp_MPDU); 获 取 接 收 MPDU 的功率(某个节点的) } 同一节点发送的 MPDU lvd_sum_power += CONST_AP_THERMAL_NOISE; 计算接收到的总功率 lvd_sum_power_dBm = 10.0 * log10(lvd_sum_power) + 30.0; op_stat_write(gvo_AP_property[lvi_AP_index].PHY_medium_stathandle, lvd_sum_power_dBm); 写入统计句柄 } 遍历所有的移动站 for (lvi_STA_index = 0; lvi_STA_index < gvi_STA_number; lvi_STA_index++) { lvi_node_index = lvi_STA_index + gvi_AP_number; lvd_sum_power = 0.0; 遍历所有的 MPDU 单元 for (lvi_MPDU_index = 0; lvi_MPDU_index < lvi_MPDU_number; lvi_MPDU_index++) { lvp_MPDU = (MPDU_T *)op_prg_list_access(gvlist_radio_channel, lvi_MPDU_index);获取 MPDU 的指针 lvd_sum_power += get_MPDU_power(lvi_node_index, lvp_MPDU); 获 取 接 收 MPDU 的功率 } lvd_sum_power += CONST_STA_THERMAL_NOISE;
lvd_sum_power_dBm = 10.0 * log10(lvd_sum_power) + 30.0; op_stat_write(gvo_STA_property[lvi_STA_index].PHY_medium_stathandle, lvd_sum_power_dBm); } 写入统计句柄 FOUT; } static void SINR 字段更新 MPDU_sinr_segment_refresh() { int lvi_MPDU_number; int lvi_MPDU_index_1; int lvi_MPDU_index_2; MPDU_T *lvp_MPDU_1; MPDU_T *lvp_MPDU_2; double lvd_signal_power; double lvd_interference_power; double lvd_noise_power; SINR_SEGMENT_T *lvp_sinr_segment; double lvd_sinr; FIN(MPDU_sinr_segment_refresh()); lvi_MPDU_number = op_prg_list_size(gvlist_radio_channel); for (lvi_MPDU_index_1 = 0; lvi_MPDU_index_1 < lvi_MPDU_number; lvi_MPDU_index_1++) { lvp_MPDU_1 = (MPDU_T *)op_prg_list_access(gvlist_radio_channel, lvi_MPDU_index_1); lvd_signal_power = 0.0; lvd_interference_power = 0.0; if (lvp_MPDU_1->destination_node_index < gvi_AP_number) { lvd_noise_power = CONST_AP_THERMAL_NOISE; } else { } lvd_noise_power = CONST_STA_THERMAL_NOISE;
for (lvi_MPDU_index_2 = 0; lvi_MPDU_index_2 < lvi_MPDU_number; lvi_MPDU_index_2++) { lvp_MPDU_2 = (MPDU_T *)op_prg_list_access(gvlist_radio_channel, lvi_MPDU_index_2); /* signal */ if ((lvp_MPDU_2->source_node_index == lvp_MPDU_1->source_node_index) && (lvp_MPDU_2->destination_node_index == lvp_MPDU_1->destination_node_index)) { if (lvd_signal_power > 0.0) { WLAN_RADIO_CHANNEL", "Error source function: MPDU_sinr_segment_refresh()", ""); op_sim_end("Error: Duplicate signal MPDU!", "Error source module: } else { get_MPDU_power(lvp_MPDU_1->destination_node_index, lvp_MPDU_2); lvd_signal_power } } /* otherwise, interference */ else { lvd_interference_power = += get_MPDU_power(lvp_MPDU_1->destination_node_index, lvp_MPDU_2); } } lvd_sinr = lvd_signal_power / (lvd_interference_power + lvd_noise_power); // linear value lvp_sinr_segment = *)op_prg_mem_alloc(sizeof(SINR_SEGMENT_T)); (SINR_SEGMENT_T lvp_sinr_segment->sinr = 10.0 * log10(lvd_sinr); lvp_sinr_segment->segment_start_time = op_sim_time(); op_prg_list_insert(lvp_MPDU_1->sinr_segment, // dB value lvp_sinr_segment, OPC_LISTPOS_TAIL); } FOUT; } static void 计算 SINR
MPDU_sinr_calculate(MPDU_T *lvp_MPDU) { int lvi_sinr_segment_number; int lvi_sinr_segment_index; SINR_SEGMENT_T *lvp_sinr_segment; double lvd_sinr; double lvd_segment_end_time; FIN(MPDU_sinr_calculate()); lvi_sinr_segment_number = op_prg_list_size(lvp_MPDU->sinr_segment); lvd_segment_end_time = lvp_MPDU->end_time; lvd_sinr = 0.0; for (lvi_sinr_segment_index = lvi_sinr_segment_number - 1; lvi_sinr_segment_index >= 0; lvi_sinr_segment_index--) { lvp_sinr_segment = (SINR_SEGMENT_T *)op_prg_list_access(lvp_MPDU->sinr_segment, lvi_sinr_segment_index); += lvd_sinr lvp_sinr_segment->sinr * (lvd_segment_end_time - lvp_sinr_segment->segment_start_time); // sum of time-weighted dB value lvd_segment_end_time = lvp_sinr_segment->segment_start_time; } lvd_sinr = lvd_sinr/(lvp_MPDU->end_time - lvp_MPDU->start_time); lvp_MPDU->sinr = lvd_sinr; op_prg_list_free(lvp_MPDU->sinr_segment); // in dB /* record MSDU SINR */ if ((lvp_MPDU->MPDU_type == MPDU_TYPE_MSDU) || (lvp_MPDU->MPDU_type == MPDU_TYPE_AMSDU) || (lvp_MPDU->MPDU_type == MPDU_TYPE_AMPDU)) { op_stat_write(svgstat_SINR, lvp_MPDU->sinr); if (lvp_MPDU->destination_node_index < gvi_AP_number) { op_stat_write(gvo_AP_property[lvp_MPDU->destination_node_index].PHY_SINR_stathandl e, lvp_MPDU->sinr); } else { op_stat_write(gvo_STA_property[lvp_MPDU->destination_node_index - gvi_AP_number].PHY_SINR_stathandle, lvp_MPDU->sinr); }
} FOUT; } Init 状态的入口程序 gvoid_radio_channel = op_id_self(); gvlist_radio_channel = op_prg_list_create(); 产生一个空的列表 声明统计句柄 SINR svgstat_SINR = op_stat_reg("PHY.SINR (dB)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL); 获取对象周围的处理器或队列 tx_end 状态的入口程序 MPDU_T *lvp_MPDU; MPDU 的指针 int lvi_MPDU_index; int lvi_MPDU_number; Ici *lvici_MPDU; MPDU 的索引号 MPDU 的数量 MPDU 的 ICI 指针 /* locate the packet related to the current interrupt */ lvi_MPDU_number = op_prg_list_size(gvlist_radio_channel);获取信道中 MPDU 的数量 for (lvi_MPDU_index = 0; lvi_MPDU_index < lvi_MPDU_number; lvi_MPDU_index++) {遍历所有的 MPDU lvp_MPDU = (MPDU_T *)op_prg_list_access(gvlist_radio_channel, lvi_MPDU_index); 获得指定位置的 MPDU if ((lvp_MPDU->end_time <= op_sim_time()) && (lvp_MPDU->end_time >= op_sim_time())) {如果仿真时间等于指定结束的时间结束,即获得了传输完成的 MPDU 的索引号 break; } } if (lvi_MPDU_index == lvi_MPDU_number) {如果没有获得相应的 MPDU op_sim_end("Error: No matched packet in radio channel is found!", "Error source module: WLAN_RADIO_CHANNEL", "", ""); } /* remove the packet from list */ 在列表的指定 位置删除数据包 lvp_MPDU = (MPDU_T *)op_prg_list_remove(gvlist_radio_channel, lvi_MPDU_index); lvici_MPDU = op_ici_create("WLAN_MPDU"); 创建 ICI op_ici_attr_set(lvici_MPDU, "MPDU_ptr", lvp_MPDU); 为给定 ICI 的 MPDU 属性赋值 op_ici_install(lvici_MPDU); 自动与调用进程预设的输出中断相关联 /* calculate average SINR for this packet */
MPDU_sinr_calculate(lvp_MPDU); 计算接收到的 SINR /* issue interrupt for the destination MAC process */ op_intrpt_schedule_process(lvp_MPDU->destination_prohandle, INTRPT_PHY_RXEND_INDICATION); op_ici_install(OPC_NIL); 自动与调用进程预设的输出中断相关联 op_sim_time(), /* update channel status for all nodes */ channel_status_refresh(); 刷新信道状态 /* update SINR for all packets in the channel */ MPDU_sinr_segment_refresh(); 刷新 SINR 字段 tx_start 状态的入口程序 MPDU_T *lvp_MPDU; Ici *lvici_MPDU; 定义了一个指向 ICI 的指针 /* retrieve the packet from ICI */ lvici_MPDU = op_intrpt_ici(); 获取与当前中断相关联的 ICI op_ici_attr_get(lvici_MPDU, "MPDU_ptr", &lvp_MPDU); 获取 MPDU 的属性值 op_ici_destroy(lvici_MPDU); 释放内存资源 /* insert the current packet into the list */将节点发送的 MPDU 放入队列中 op_prg_list_insert(gvlist_radio_channel, lvp_MPDU, OPC_LISTPOS_TAIL);从队列尾部插入 op_intrpt_schedule_self(lvp_MPDU->end_time, INTRPT_PHY_TXEND); 设置传输结束自中断 /* update channel status for all nodes */ channel_status_refresh(); 信道状态刷新计算来自同一节点 MPDU 的功率 /* update SINR for all packets in the channel */ MPDU_sinr_segment_refresh(); SINR 字段刷新
分享到:
收藏