图为 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 字段刷新