Commit 9f6b06a3 authored by Aurélien Delrieu's avatar Aurélien Delrieu

Merge branch 'dev_review_phy_layer' into dev

parents 016ddd0c bf588e4f
......@@ -359,4 +359,8 @@
// OTHERS //
/////////////
#define ENCODE_CNI_EXT "encodeCniExt"
#define UP "Up"
#define DOWN "Down"
#define UP_LOWER_CASE "up"
#define DOWN_LOWER_CASE "down"
#endif
......@@ -67,18 +67,24 @@ bool Plugin::getLanAdaptationPlugin(string name,
return utils.getLanAdaptationPlugin(name, lan_adaptation);
}
bool Plugin::getPhysicalLayerPlugins(string att_pl_name,
string min_pl_name,
string err_pl_name,
AttenuationModelPlugin **attenuation,
MinimalConditionPlugin **minimal,
bool Plugin::getAttenuationPlugin(string att_pl_name,
AttenuationModelPlugin **attenuation)
{
return utils.getAttenuationPlugin(att_pl_name,
attenuation);
}
bool Plugin::getMinimalConditionPlugin(string min_pl_name,
MinimalConditionPlugin **minimal)
{
return utils.getMinimalConditionPlugin(min_pl_name,
minimal);
}
bool Plugin::getErrorInsertionPlugin(string err_pl_name,
ErrorInsertionPlugin **error)
{
return utils.getPhysicalLayerPlugins(att_pl_name,
min_pl_name,
err_pl_name,
attenuation,
minimal,
return utils.getErrorInsertionPlugin(err_pl_name,
error);
}
......
......@@ -87,21 +87,33 @@ class Plugin
LanAdaptationPlugin **lan_adaptation);
/**
* @brief get physical layer plugins
* @brief get physical layer attenuation plugin
*
* @param att_pl_name The name of the attenuation model plugin
* @param min_pl_name The name of the minimal condition plugin
* @param err_pl_name The name of the erroe insertion plugin
* @param attenuation The attenuation model plugin
* @return true on success, false otherwise
*/
static bool getAttenuationPlugin(string att_pl_name,
AttenuationModelPlugin **attenuation);
/**
* @brief get physical layer minimal condition plugin
*
* @param min_pl_name The name of the minimal condition plugin
* @param minimal The minimal condition plugin
* @return true on success, false otherwise
*/
static bool getMinimalConditionPlugin(string min_pl_name,
MinimalConditionPlugin **minimal);
/**
* @brief get physical layer error insertion plugin
*
* @param err_pl_name The name of the erroe insertion plugin
* @param error The error insertion plugin
* @return true on success, false otherwise
*/
static bool getPhysicalLayerPlugins(string att_pl_name,
string min_pl_name,
string err_pl_name,
AttenuationModelPlugin **attenuation,
MinimalConditionPlugin **minimal,
static bool getErrorInsertionPlugin(string err_pl_name,
ErrorInsertionPlugin **error);
/**
......
......@@ -389,12 +389,8 @@ bool PluginUtils::getLanAdaptationPlugin(string name,
return true;
};
bool PluginUtils::getPhysicalLayerPlugins(string att_pl_name,
string min_pl_name,
string err_pl_name,
AttenuationModelPlugin **attenuation,
MinimalConditionPlugin **minimal,
ErrorInsertionPlugin **error)
bool PluginUtils::getAttenuationPlugin(string att_pl_name,
AttenuationModelPlugin **attenuation)
{
fn_create create;
......@@ -419,6 +415,15 @@ bool PluginUtils::getPhysicalLayerPlugins(string att_pl_name,
this->plugins.push_back(*attenuation);
}
return true;
};
bool PluginUtils::getMinimalConditionPlugin(string min_pl_name,
MinimalConditionPlugin **minimal)
{
fn_create create;
if(min_pl_name.size() > 0)
{
create = this->minimal[min_pl_name];
......@@ -440,6 +445,15 @@ bool PluginUtils::getPhysicalLayerPlugins(string att_pl_name,
this->plugins.push_back(*minimal);
}
return true;
};
bool PluginUtils::getErrorInsertionPlugin(string err_pl_name,
ErrorInsertionPlugin **error)
{
fn_create create;
if(err_pl_name.size() > 0)
{
create = this->error[err_pl_name];
......
......@@ -122,21 +122,33 @@ class PluginUtils
SatDelayPlugin **sat_delay);
/**
* @brief get physical layer plugins
* @brief get physical layer attenuation plugin
*
* @param att_pl_name The name of the attenuation model plugin
* @param min_pl_name The name of the minimal condition plugin
* @param err_pl_name The name of the erroe insertion plugin
* @param attenuation The attenuation model plugin
* @return true on success, false otherwise
*/
bool getAttenuationPlugin(string att_pl_name,
AttenuationModelPlugin **attenuation);
/**
* @brief get physical layer minimal condition plugin
*
* @param min_pl_name The name of the minimal condition plugin
* @param minimal The minimal condition plugin
* @return true on success, false otherwise
*/
bool getMinimalConditionPlugin(string min_pl_name,
MinimalConditionPlugin **minimal);
/**
* @brief get physical layer error insertion plugin
*
* @param err_pl_name The name of the erroe insertion plugin
* @param error The error insertion plugin
* @return true on success, false otherwise
*/
bool getPhysicalLayerPlugins(string att_pl_name,
string min_pl_name,
string err_pl_name,
AttenuationModelPlugin **attenuation,
MinimalConditionPlugin **minimal,
bool getErrorInsertionPlugin(string err_pl_name,
ErrorInsertionPlugin **error);
/**
......
......@@ -2753,6 +2753,13 @@ bool BlockDvbTal::Upward::onRcvDvbFrame(DvbFrame *dvb_frame)
if(this->state == state_running)
{
if(this->with_phy_layer && dvb_frame->getMessageType() == MSG_TYPE_TTP)
{
// get ACM parameters that will be transmited to GW in SAC
double cni = dvb_frame->getCn();
this->setRequiredCniInput(this->tal_id, cni);
}
if(!this->shareFrame(dvb_frame))
{
LOG(this->log_receive, LEVEL_ERROR,
......
......@@ -153,7 +153,7 @@ bool DvbS2Std::onRcvFrame(DvbFrame *dvb_frame,
{
// the BB frame is not robust enough to be decoded, drop it
// TODO Error but the frame is maybe not for this st
LOG(this->log_rcv_from_down, LEVEL_ERROR,
LOG(this->log_rcv_from_down, LEVEL_INFO,
"the terminal is able to decode MODCOD %d (SNR %f), "
"the received BB frame is encoded with MODCOD %d (SNR %f) "
"that is not robust enough, so emulate a lost BB frame\n",
......
......@@ -559,21 +559,11 @@ bool SatGw::updateFmt(DvbFrame *dvb_frame,
{
Sac *sac = (Sac *)dvb_frame;
src_tal_id = sac->getTerminalId();
if(!src_tal_id)
{
LOG(this->log_receive, LEVEL_ERROR,
"unable to read source terminal ID in "
"frame, won't be able to update C/N "
"value\n");
}
else
{
cn = dvb_frame->getCn();
LOG(this->log_receive, LEVEL_INFO,
"Uplink CNI for terminal %u = %f\n",
src_tal_id, cn);
this->setRequiredCniInput(src_tal_id, cn);
}
cn = dvb_frame->getCn();
LOG(this->log_receive, LEVEL_INFO,
"Uplink CNI for terminal %u = %f\n",
src_tal_id, cn);
this->setRequiredCniInput(src_tal_id, cn);
break;
}
case MSG_TYPE_DVB_BURST:
......
......@@ -624,11 +624,12 @@ bool BlockDvbSatRegen::UpwardRegen::addSt(SatGw *current_gw,
return true;
}
bool BlockDvbSatRegen::UpwardRegen::handleCorrupted(DvbFrame *UNUSED(dvb_frame))
bool BlockDvbSatRegen::UpwardRegen::handleCorrupted(DvbFrame *dvb_frame)
{
// in regenerative case we need to handle the corrupted frame in order
// to get statistics
return false;
LOG(this->log_receive, LEVEL_INFO,
"frame was corrupted by physical layer, drop it.");
delete dvb_frame;
return true;
}
......
......@@ -64,7 +64,7 @@
#define IS_ATTENUATED_FRAME(msg_type) \
(msg_type == MSG_TYPE_BBFRAME || msg_type == MSG_TYPE_DVB_BURST || \
msg_type == MSG_TYPE_SALOHA_DATA || msg_type == MSG_TYPE_SALOHA_CTRL || \
msg_type == MSG_TYPE_SAC)
msg_type == MSG_TYPE_SAC || msg_type == MSG_TYPE_TTP)
/// Whether the frame has to be delayed
#define IS_DELAYED_FRAME(msg_type) \
......
/*
*
* OpenSAND is an emulation testbed aiming to represent in a cost effective way a
* satellite telecommunication system for research and engineering activities.
*
*
* Copyright © 2017 CNES
* Copyright © 2017 TAS
*
*
* This file is part of the OpenSAND testbed.
*
*
* OpenSAND is free software : you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see http://www.gnu.org/licenses/.
*
*/
/**
* @file AttenuationHandler.cpp
* @brief Process the attenuation
* @author Santiago PENA LUQUE <santiago.penaluque@cnes.fr>
* @author Aurélien DELRIEU <adelrieu@toulouse.viveris.com>
*/
#include "AttenuationHandler.h"
#include "Plugin.h"
#include "BBFrame.h"
#include "DvbRcsFrame.h"
#include "OpenSandCore.h"
#include <opensand_output/Output.h>
#include <opensand_conf/conf.h>
#include <math.h>
AttenuationHandler::AttenuationHandler(OutputLog *log_channel):
minimal_condition_model(NULL),
error_insertion_model(NULL),
log_channel(log_channel),
probe_minimal_condition(NULL),
probe_drops(NULL)
{
}
AttenuationHandler::~AttenuationHandler()
{
}
bool AttenuationHandler::initialize(const string &link_section, OutputLog *log_init)
{
string minimal_type;
string error_type;
// Get parameters
if(!Conf::getValue(Conf::section_map[link_section],
MINIMAL_CONDITION_TYPE,
minimal_type))
{
LOG(log_init, LEVEL_ERROR,
"section '%s': missing parameter '%s'",
link_section,
MINIMAL_CONDITION_TYPE);
return false;
}
LOG(log_init, LEVEL_NOTICE,
"minimal_condition_type = %s", minimal_type.c_str());
if(!Conf::getValue(Conf::section_map[link_section],
ERROR_INSERTION_TYPE,
error_type))
{
LOG(log_init, LEVEL_ERROR,
"section '%s': missing parameter '%s'",
link_section, ERROR_INSERTION_TYPE);
return false;
}
LOG(log_init, LEVEL_NOTICE,
"error_insertion_type = %s", error_type.c_str());
// Load plugins
if(!Plugin::getMinimalConditionPlugin(minimal_type, &this->minimal_condition_model))
{
LOG(log_init, LEVEL_ERROR,
"Unable to get the physical layer minimal condition plugin");
return false;
}
if(!Plugin::getErrorInsertionPlugin(error_type, &this->error_insertion_model))
{
LOG(log_init, LEVEL_ERROR,
"Unable to get the physical layer error insertion plugin");
return false;
}
// Initialize plugins
if(!this->minimal_condition_model->init())
{
LOG(log_init, LEVEL_ERROR,
"Unable to initialize the physical layer minimal condition plugin %s",
minimal_type.c_str());
return false;
}
if(!this->error_insertion_model->init())
{
LOG(log_init, LEVEL_ERROR,
"Unable to initialize the physical layer error insertion plugin %s",
minimal_type.c_str());
return false;
}
// Initialize probes
this->probe_minimal_condition = Output::registerProbe<float>("Phy.minimal_condition",
"dB", true,
SAMPLE_MAX);
this->probe_drops = Output::registerProbe<int>("Phy.drops",
"frame number", true,
// we need to sum the drops here !
SAMPLE_SUM);
return true;
}
bool AttenuationHandler::process(DvbFrame *dvb_frame, double cn_total)
{
fmt_id_t modcod_id = 0;
double min_cn;
Data payload;
// Consider that the packet is not dropped (if its dropped, the probe
// will be updated later), so that the probe emits a 0 value if necessary.
this->probe_drops->put(0);
// Get the MODCOD used to send DVB frame
// (keep the complete header because we carry useful data)
switch(dvb_frame->getMessageType())
{
case MSG_TYPE_BBFRAME:
{
// TODO BBFrame *bbframe = dynamic_cast<BBFrame *>(dvb_frame);
BBFrame *bbframe = (BBFrame *)dvb_frame;
modcod_id = bbframe->getModcodId();
payload = bbframe->getPayload();
}
break;
case MSG_TYPE_DVB_BURST:
{
// TODO DvbRcsFrame *dvb_rcs_frame = dynamic_cast<DvbRcsFrame *>(dvb_frame);
DvbRcsFrame *dvb_rcs_frame = (DvbRcsFrame *)dvb_frame;
modcod_id = dvb_rcs_frame->getModcodId();
payload = dvb_rcs_frame->getPayload();
}
break;
default:
{
// This message, even though it carries C/N information (is attenuated)
// is not encoded using a MODCOD, and cannot be dropped.
return true;
}
}
LOG(this->log_channel, LEVEL_INFO,
"Receive frame with MODCOD %u, total C/N = %.2f", modcod_id, cn_total);
// Update minimal condition threshold
if(!this->minimal_condition_model->updateThreshold(modcod_id, dvb_frame->getMessageType()))
{
LOG(this->log_channel, LEVEL_ERROR,
"Threshold update failed");
return false;
}
// TODO this would be better to get minimal condition per source terminal
// if we are on regenerative satellite or GW
// On terminals, here we receive all BBFrame on the spot,
// some may not contain packets for us but we will still count them in stats
// We would have to parse frames in order to remove them from
// statistics, this is not efficient
// With physcal layer ACM loop, these frame would be mark as corrupted
min_cn = this->minimal_condition_model->getMinimalCN();
this->probe_minimal_condition->put(min_cn);
LOG(this->log_channel, LEVEL_INFO,
"Minimal condition value for MODCOD %u: %.2f dB", modcod_id, min_cn);
// Insert error if required
if(!this->error_insertion_model->isToBeModifiedPacket(cn_total, min_cn))
{
return true;
}
LOG(this->log_channel, LEVEL_DEBUG,
"Error insertion is required");
if(!this->error_insertion_model->modifyPacket(payload))
{
LOG(this->log_channel, LEVEL_ERROR,
"Error insertion failed");
return false;
}
dvb_frame->setCorrupted(true);
this->probe_drops->put(1);
LOG(this->log_channel, LEVEL_NOTICE,
"Received frame was corrupted");
return true;
}
/*
*
* OpenSAND is an emulation testbed aiming to represent in a cost effective way a
* satellite telecommunication system for research and engineering activities.
*
*
* Copyright © 2017 CNES
* Copyright © 2017 TAS
*
*
* This file is part of the OpenSAND testbed.
*
*
* OpenSAND is free software : you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see http://www.gnu.org/licenses/.
*
*/
/**
* @file AttenuationHandler.h
* @brief Process the attenuation
* @author Santiago PENA LUQUE <santiago.penaluque@cnes.fr>
* @author Aurélien DELRIEU <adelrieu@toulouse.viveris.com>
*/
#ifndef ATTENUATION_HANDLER_H
#define ATTENUATION_HANDLER_H
#include "PhysicalLayerPlugin.h"
#include "DvbFrame.h"
#include <opensand_output/Output.h>
#include <string>
using std::string;
/**
* @class AttenuationHandler
* @brief Process the attenuation
*/
class AttenuationHandler
{
private:
/** Minimal Conditions (minimun C/N to have QEF communications)
* of global link (i.e. considering the Modcod scheme)
*/
MinimalConditionPlugin *minimal_condition_model;
/// Error Insertion object : defines who error will be introduced
ErrorInsertionPlugin *error_insertion_model;
/// Log
OutputLog *log_channel;
/// Probes
Probe<float> *probe_minimal_condition;
Probe<int> *probe_drops;
public:
/**
* @brief Constructor of the attenuation handler
*
* @param log_channel the log output to use during attenuation processing
*/
AttenuationHandler(OutputLog *log_channel);
/**
* @brief Destroy the attenuation handler
*/
virtual ~AttenuationHandler();
/**
* @brief Initialize the attenuation handler
*
* @param link_section the link section for configuration
* @param log_init the log output to use during initialization
*
* @return true on success, false otherwise
*/
bool initialize(const string &link_section, OutputLog *log_init);
/**
* @brief Process the attenuation on a DVB frame with a specific C/N
*
* @param dvb_frame the DVB frame
* @param total_cn the specific C/N
*
* @return true on success, false otherwise
*/
bool process(DvbFrame *dvb_frame, double cn_total);
};
#endif
......@@ -41,15 +41,18 @@
#ifndef BLOCK_PHYSICAL_LAYER_H
#define BLOCK_PHYSICAL_LAYER_H
#include "PhyChannel.h"
#include "OpenSandCore.h"
#include "GroundPhysicalChannel.h"
#include "AttenuationHandler.h"
#include <opensand_rt/Rt.h>
#include <opensand_output/Output.h>
#include <string>
#include <map>
using std::string;
using std::map;
/**
* @class BlockPhysicalLayer
......@@ -58,114 +61,265 @@
class BlockPhysicalLayer: public Block
{
public:
/**
* Build a physical layer block
*
* @param name The name of the block
* @param name The mac id of the terminal
* @class Upward
* @brief Ground Upward Physical Layer Channel
*/
BlockPhysicalLayer(const string &name, tal_id_t mac_id);
class Upward: public GroundPhysicalChannel, public RtUpward
{
private:
/// Probes
Probe<float> *probe_total_cn;
protected:
/// The attenuation process
AttenuationHandler *attenuation_hdl;
/**
* @brief Forward the frame to the next channel
*
* @param dvb_frame the DVB frame to forward
*
* @return true on success, false otherwise
*/
bool forwardPacket(DvbFrame *dvb_frame);
/**
* @brief Forward the frame to the next channel after attenuation application
*
* @param dvb_frame the DVB frame to forward
*
* @return true on success, false otherwise
*/
bool forwardPacketWithoutAttenuation(DvbFrame *dvb_frame);
/**
* @brief Forward the frame to the next channel
*
* @param dvb_frame the DVB frame to forward
*
* @return true on success, false otherwise
*/
bool forwardPacketWithAttenuation(DvbFrame *dvb_frame);
/**
* @brief Get the C/N fot the current DVB frame
*
* @param dvb_frame the current DVB frame
*
* @return the current C/N
*/
virtual double getCn(DvbFrame *dvb_frame) const = 0;
public:
/**
* @brief Constructor of the ground upward physical channel
*
* @param name the name of the channel
* @param mac_id the id of the ST or of the GW
*/
Upward(const string &name, tal_id_t mac_id);
/**
* @brief Destroy the Channel
*/
virtual ~Upward();
/**
* @brief Initialize the ground upward physical channel
*
* @return true on success, false otherwise
*/
virtual bool onInit();
/**
* @brief Event processing
*
* @param event the event to process
*
* @return true on success, false otherwise
*/
bool onEvent(const RtEvent *const event);
};
/**
* Destroy the PhysicalLayer block
* @class UpwardTransp
* @brief Ground Upward Physical Layer Channel for transparent satellite
*/
~BlockPhysicalLayer();
class UpwardTransp: public Upward
{
public:
/**
* @brief Constructor of the ground upward physical channel
*
* @param name the name of the channel
* @param mac_id the id of the ST or of the GW
*/
UpwardTransp(const string &name, tal_id_t mac_id):
Upward(name, mac_id)
{
}
// initialization method
bool onInit();
/**
* @brief Destroy the Channel
*/
virtual ~UpwardTransp()
{
}
class Upward: public RtUpward, PhyChannel
/**
* @brief Get the C/N fot the current DVB frame