41 #include <libxml/parser.h>    42 #include <libxml/xmlschemas.h>    46   const char * pzSchema=
"\    47 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\    48   <xs:simpleType name='SIPrefixType'>\    49     <xs:restriction base='xs:token'>\    50       <xs:pattern value='[0-9]+(.[0-9]+){0,1}(G|M|K){0,1}'/>\    53   <xs:simpleType name='SINRType'>\    54     <xs:restriction base='xs:token'>\    55       <xs:pattern value='[+-]?(0|[1-9][0-9]*)(.[0-9]{1,2})?'/>\    58   <xs:simpleType name='PORType'>\    59     <xs:restriction base='xs:token'>\    60       <xs:pattern value='(0|[1-9][0-9]*)(.[0-9]{1,2})?'/>\    63   <xs:element name='tdmabasemodel-pcr'>\    66         <xs:element name='datarate' maxOccurs='unbounded'>\    69                <xs:element name='entry' maxOccurs='unbounded'>\    71                    <xs:attribute name='sinr' type='SINRType' use='optional'/>\    72                    <xs:attribute name='por' type='PORType' use='optional'/>\    76             <xs:attribute name='bps' type='SIPrefixType' use='required'/>\    80       <xs:attribute name='packetsize' type='xs:unsignedShort' use='required'/>\    85   std::string scaleFloatToInteger(
const std::string & sValue)
    87     const int iScaleFactor{2};
    88     std::string sTmpParameter{sValue};
    91     std::string::size_type indexPoint =  sTmpParameter.find(
".",0);
    93     if(indexPoint != std::string::npos)
    95         std::string::size_type numberOfDigitsAfterPoint =
    96           sTmpParameter.size() - indexPoint - 1;
    98         if(numberOfDigitsAfterPoint > iScaleFactor)
   101             sTmpParameter.insert(sTmpParameter.size() - (numberOfDigitsAfterPoint - iScaleFactor),
   107             sTmpParameter.append(iScaleFactor - numberOfDigitsAfterPoint,
'0');
   111         sTmpParameter.erase(indexPoint,1);
   116         sTmpParameter.append(iScaleFactor,
'0');
   119     return sTmpParameter;
   124   u64DefaultCurveDataRate_{},
   125   modifierLengthBytes_{}{}
   129   xmlDocPtr pSchemaDoc{xmlReadMemory(pzSchema,
   131                                      "file:///tdmabasemodelpcr.xsd",
   136       throw makeException<ConfigurationException>(
"unable to open schema");
   139   xmlSchemaParserCtxtPtr pParserContext{xmlSchemaNewDocParserCtxt(pSchemaDoc)};
   143       throw makeException<ConfigurationException>(
"bad schema context");
   146   xmlSchemaPtr pSchema{xmlSchemaParse(pParserContext)};
   150       throw makeException<ConfigurationException>(
"bad schema parser");
   153   xmlSchemaValidCtxtPtr pSchemaValidCtxtPtr{xmlSchemaNewValidCtxt(pSchema)};
   155   if(!pSchemaValidCtxtPtr)
   157       throw makeException<ConfigurationException>(
"bad schema valid context");
   160   xmlSchemaSetValidOptions(pSchemaValidCtxtPtr,XML_SCHEMA_VAL_VC_I_CREATE);
   162   xmlDocPtr pDoc = xmlReadFile(sPCRFileName.c_str(),
nullptr,0);
   164   if(xmlSchemaValidateDoc(pSchemaValidCtxtPtr, pDoc))
   166       throw makeException<ConfigurationException>(
"invalid document: %s",
   167                                                   sPCRFileName.c_str());
   170   xmlNodePtr pRoot = xmlDocGetRootElement(pDoc);
   172   xmlChar * pPacketSize = xmlGetProp(pRoot,BAD_CAST 
"packetsize");
   176   xmlFree(pPacketSize);
   178   for(xmlNodePtr pDataRateNode = pRoot->children;
   179       pDataRateNode != 
nullptr;
   180       pDataRateNode = pDataRateNode->next)
   182       if(!xmlStrcmp(pDataRateNode->name, BAD_CAST 
"datarate"))
   184           xmlChar * pDataRatebps = xmlGetProp(pDataRateNode,BAD_CAST 
"bps");
   186           std::uint64_t u64DataRatebps =
   189           xmlFree(pDataRatebps);
   191           if(dataRateTable_.empty())
   193               u64DefaultCurveDataRate_ = u64DataRatebps;
   197           std::int32_t i32MinScaledSINR{std::numeric_limits<std::int32_t>::max()};
   198           std::int32_t i32MaxScaledSINR{std::numeric_limits<std::int32_t>::lowest()};
   200           for(xmlNodePtr pEntryNode = pDataRateNode->children;
   201               pEntryNode != 
nullptr;
   202               pEntryNode = pEntryNode->next)
   204               if(!xmlStrcmp(pEntryNode->name, BAD_CAST 
"entry"))
   206                   xmlChar * pSINR = xmlGetProp(pEntryNode,BAD_CAST 
"sinr");
   207                   xmlChar * pPOR = xmlGetProp(pEntryNode,BAD_CAST 
"por");
   209                   std::int32_t i32ScaledSINR =
   213                     curve.insert(std::make_pair(i32ScaledSINR,
   218                       throw makeException<ConfigurationException>(
"duplicate PCR SINR value for datarate: %zu sinr: %s in %s",
   220                                                                   reinterpret_cast<const char *
>(pSINR),
   221                                                                   sPCRFileName.c_str());
   227                   i32MinScaledSINR = std::min(i32ScaledSINR,i32MinScaledSINR);
   228                   i32MaxScaledSINR = std::max(i32ScaledSINR,i32MaxScaledSINR);
   232           Curve interpolation{};
   234           auto iter = curve.begin();
   236           while(iter != curve.end())
   238               auto x0 = iter->first;
   239               auto y0 = iter->second;
   243               if(iter != curve.end())
   245                   auto x1 = iter->first;
   246                   auto y1 = iter->second;
   248                   auto slope = (y1 - y0) / (x1 - x0);
   250                   for(
auto i = x0; i < x1; ++i)
   252                       interpolation.insert({i,y1 - (x1 - i) * slope});
   257           curve.insert(interpolation.begin(),interpolation.end());
   259           auto ret = dataRateTable_.insert(std::make_pair(u64DataRatebps,
   260                                                           std::make_tuple(i32MinScaledSINR,
   266               throw makeException<ConfigurationException>(
"duplicate PCR datarate: %zu in %s",
   268                                                           sPCRFileName.c_str());
   274   xmlFreeDoc(pSchemaDoc);
   282                                               size_t packetLengthBytes)
   284   auto iter = dataRateTable_.find(u64DataRatebps);
   286   if(iter == dataRateTable_.end())
   288       iter = dataRateTable_.find(u64DefaultCurveDataRate_);
   291   std::int32_t i32MinScaledSINR = std::get<0>(iter->second);
   292   std::int32_t i32MaxScaledSINR = std::get<1>(iter->second);
   293   Curve & curve = std::get<2>(iter->second);
   295   std::int32_t i32Scaled{
static_cast<std::int32_t
>(fSINR * 100)};
   297   if(i32Scaled < i32MinScaledSINR)
   302   if(i32Scaled > i32MaxScaledSINR)
   307   auto curveIter = curve.find(i32Scaled);
   309   if(curveIter != curve.end())
   311       auto por = curveIter->second;
   313       if(modifierLengthBytes_)
   315           por = powf(por, packetLengthBytes / static_cast<float>(modifierLengthBytes_));
   325 EMANE::Models::TDMA::PORManager::PORManager::dump()
   329   for(
const auto & dataRateEntry : dataRateTable_)
   333       for(
const auto & porEntry : std::get<2>(dataRateEntry.second))
   335           entries.insert({porEntry.first / 100.0, porEntry.second});
   338       ret.insert({dataRateEntry.first,entries});
 void load(const std::string &sPCRFileName)
 
std::map< std::uint64_t, CurveDump > CurveDumps
 
std::map< float, float > CurveDump
 
std::uint16_t toUINT16(std::uint16_t u16Min=std::numeric_limits< std::uint16_t >::min(), std::uint16_t u16Max=std::numeric_limits< std::uint16_t >::max()) const
 
std::uint64_t toUINT64(std::uint64_t u64Min=std::numeric_limits< std::uint64_t >::min(), std::uint64_t u64Max=std::numeric_limits< std::uint64_t >::max()) const
 
float getPOR(std::uint64_t u64DataRate, float fSINR, size_t packetLengthBytes)
 
std::int32_t toINT32(std::int32_t i32Min=std::numeric_limits< std::int32_t >::min(), std::int32_t i32Max=std::numeric_limits< std::int32_t >::max()) const
 
Parameter conversion class with range checks.