EMANE  1.2.1
antennaprofilemanifest.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "antennaprofilemanifest.h"
36 #include "positionneu.h"
37 #include "emane/constants.h"
38 
39 #include <libxml/parser.h>
40 
41 void EMANE::AntennaProfileManifest::load(const std::string & sAntennaProfileURI)
42 {
43  xmlParserCtxtPtr pContext{xmlNewParserCtxt()};
44 
45  if(!pContext)
46  {
47  throw AntennaProfileException{"Unable to create a parser context"};
48  }
49 
50  xmlDocPtr pDoc{xmlCtxtReadFile(pContext, sAntennaProfileURI.c_str(), NULL, XML_PARSE_DTDVALID)};
51 
52  if(!pDoc)
53  {
54 
55  xmlFreeParserCtxt(pContext);
56  throw makeException<AntennaProfileException>("Unable to read %s",sAntennaProfileURI.c_str());
57  }
58 
59  if(pContext->valid == false)
60  {
61  xmlFreeDoc(pDoc);
62  xmlFreeParserCtxt(pContext);
63  throw makeException<AntennaProfileException>("Validation failure %s",sAntennaProfileURI.c_str());
64  }
65 
66  xmlNodePtr pRoot{xmlDocGetRootElement(pDoc)};
67 
68  if(!pRoot)
69  {
70  xmlFreeDoc(pDoc);
71  xmlFreeParserCtxt(pContext);
72  throw makeException<AntennaProfileException>("Invalid document root %s",
73  sAntennaProfileURI.c_str());
74  }
75 
76  for(xmlNodePtr pNode = pRoot->children; pNode; pNode = pNode->next)
77  {
78  if(pNode->type == XML_ELEMENT_NODE)
79  {
80  if(!xmlStrcmp(pNode->name,BAD_CAST "profile"))
81  {
82  xmlChar * pId{xmlGetProp(pNode,BAD_CAST "id")};
83 
84  std::uint16_t u16Id =
85  EMANE::Utils::ParameterConvert(reinterpret_cast<const char *>(pId)).toUINT16();
86 
87  xmlFree(pId);
88 
89  xmlChar * pAntennaPatternURI{xmlGetProp(pNode,BAD_CAST "antennapatternuri")};
90 
91  std::string sAntennaPatternURI{ reinterpret_cast<const char *>(pAntennaPatternURI)};
92 
93  xmlFree(pAntennaPatternURI);
94 
95  xmlChar * pBlockagePatternURI{xmlGetProp(pNode,BAD_CAST "blockagepatternuri")};
96 
97  std::string sBlockagePatternURI{};
98 
99  if(pBlockagePatternURI)
100  {
101  sBlockagePatternURI = reinterpret_cast<const char *>(pBlockagePatternURI);
102 
103  xmlFree(pBlockagePatternURI);
104  }
105 
106  PositionNEU antennaPlacement{};
107 
108  for(xmlNodePtr pChileNode = pNode->children; pChileNode; pChileNode = pChileNode->next)
109  {
110  if(pChileNode->type == XML_ELEMENT_NODE)
111  {
112  if(!xmlStrcmp(pChileNode->name,BAD_CAST "placement"))
113  {
114  xmlChar * pNorth{xmlGetProp(pChileNode,BAD_CAST "north")};
115 
116  double dNorth =
117  EMANE::Utils::ParameterConvert(reinterpret_cast<const char *>(pNorth)).toDouble();
118 
119  xmlFree(pNorth);
120 
121  xmlChar * pEast{xmlGetProp(pChileNode,BAD_CAST "east")};
122  double dEast =
123  EMANE::Utils::ParameterConvert(reinterpret_cast<const char *>(pEast)).toDouble();
124 
125  xmlFree(pEast);
126 
127  xmlChar * pUp{xmlGetProp(pChileNode,BAD_CAST "up")};
128 
129  double dUp =
130  EMANE::Utils::ParameterConvert(reinterpret_cast<const char *>(pUp)).toDouble();
131 
132  xmlFree(pUp);
133 
134  antennaPlacement = PositionNEU{dNorth,dEast,dUp};
135  }
136  }
137  }
138 
139  AntennaPattern * pAntennaPattern{};
140 
141  auto iter = antennaPatternStore_.find(sAntennaPatternURI);
142 
143  if(iter == antennaPatternStore_.end())
144  {
145  pAntennaPattern = new AntennaPattern{sAntennaPatternURI,"antennapattern",DBM_MIN};
146 
147  antennaPatternStore_.insert(std::make_pair(sAntennaPatternURI,
148  std::unique_ptr<AntennaPattern>(pAntennaPattern)));
149  }
150  else
151  {
152  pAntennaPattern = iter->second.get();
153  }
154 
155 
156  AntennaPattern * pBlockagePattern{};
157 
158  if(!sBlockagePatternURI.empty())
159  {
160  auto iter = antennaPatternStore_.find(sBlockagePatternURI);
161 
162  if(iter == antennaPatternStore_.end())
163  {
164  pBlockagePattern = new AntennaPattern{sBlockagePatternURI,"blockagepattern",0};
165 
166  antennaPatternStore_.insert(std::make_pair(sBlockagePatternURI,
167  std::unique_ptr<AntennaPattern>(pBlockagePattern)));
168  }
169  else
170  {
171  pBlockagePattern = iter->second.get();
172  }
173  }
174 
175  if(!profiles_.insert(std::make_pair(u16Id,
176  std::make_tuple(pAntennaPattern,pBlockagePattern,antennaPlacement))).second)
177  {
178  throw makeException<AntennaProfileException>("Duplicate antenna profile id %hu",u16Id);
179  }
180  }
181  }
182  }
183 
184  xmlFreeDoc(pDoc);
185  xmlFreeParserCtxt(pContext);
186 }
187 
188 
189 std::pair<std::tuple<EMANE::AntennaPattern *,EMANE::AntennaPattern *,EMANE::PositionNEU>,bool>
191 {
192  const auto iter = profiles_.find(antennaProfileId);
193 
194  if(iter != profiles_.end())
195  {
196  return {iter->second,true};
197  }
198 
199  return {{},false};
200 }
void load(const std::string &sAntennaProfileURI)
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
double toDouble(double dMin=std::numeric_limits< double >::lowest(), double dMax=std::numeric_limits< double >::max()) const
std::uint16_t AntennaProfileId
Definition: types.h:57
const float DBM_MIN
Definition: constants.h:39
Parameter conversion class with range checks.
std::pair< std::tuple< AntennaPattern *, AntennaPattern *, PositionNEU >, bool > getProfileInfo(AntennaProfileId antennaProfileId) const