Line data Source code
1 : #include <iostream>
2 : /*
3 : ________________________________________________________________________
4 : | |
5 : | _ _ _ _ |
6 : | | (_) | | | | |
7 : | __| |_ __ _ _ __ ___ ___| |_ ___ _ __ ___ ___ __| | ___ ___ |
8 : | / _` | |/ _` | '_ ` _ \ / _ \ __/ _ \ '__/ __/ _ \ / _` |/ _ \/ __| |
9 : | | (_| | | (_| | | | | | | __/ || __/ | | (_| (_) | (_| | __/ (__ |
10 : | \__,_|_|\__,_|_| |_| |_|\___|\__\___|_| \___\___/ \__,_|\___|\___| |
11 : | |
12 : |________________________________________________________________________|
13 :
14 : C++ CODEC FOR DIAMETER PROTOCOL (RFC 6733)
15 : Version 0.0.z
16 : https://github.com/testillano/diametercodec
17 :
18 : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
19 : SPDX-License-Identifier: MIT
20 : Copyright (c) 2021 Eduardo Ramos
21 :
22 : Permission is hereby granted, free of charge, to any person obtaining a copy
23 : of this software and associated documentation files (the "Software"), to deal
24 : in the Software without restriction, including without limitation the rights
25 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 : copies of the Software, and to permit persons to whom the Software is
27 : furnished to do so, subject to the following conditions:
28 :
29 : The above copyright notice and this permission notice shall be included in all
30 : copies or substantial portions of the Software.
31 :
32 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 : SOFTWARE.
39 : */
40 :
41 : // Project
42 : #include <ert/diametercodec/stack/Avp.hpp>
43 : #include <ert/diametercodec/stack/Dictionary.hpp>
44 : #include <ert/diametercodec/stack/Format.hpp>
45 : #include <ert/tracing/Logger.hpp>
46 :
47 : namespace ert {
48 : namespace diametercodec {
49 : namespace stack {
50 :
51 62727 : bool Avp::isChild(const core::AvpId& avpId) const {
52 62727 : const Format* format = getFormat();
53 :
54 62727 : if (!format->isGrouped()) return false;
55 :
56 270512 : for (const auto& it : avprules_)
57 209683 : if (avpId == (it.second.getId())) return true;
58 :
59 60829 : return false;
60 : }
61 :
62 433838 : const Format* Avp::getFormat() const { return dictionary_->getFormat(format_name_); }
63 :
64 20807 : void Avp::addLabel(const std::string& data, const std::string& alias) {
65 20807 : const Format* format = getFormat();
66 :
67 20807 : if (format->isGrouped())
68 0 : throw std::runtime_error("Cannot add 'data-alias' entry on a grouped Avp");
69 : else
70 20807 : labels_[data] = alias;
71 :
72 20807 : LOGWARNING(
73 :
74 : if (format->isEnumerated() && !allowEnum(atoi(data.c_str()))) {
75 : ert::tracing::Logger::warning(
76 : ert::tracing::Logger::asString(
77 : "Makes no sense adding alias '%s' for enum value '%s' out of range ('%s'), Avp '%s'", alias.c_str(),
78 : data.c_str(), getEnums(), name_.c_str()),
79 : ERT_FILE_LOCATION);
80 : });
81 20807 : }
82 :
83 9639 : void Avp::addAvpRule(const AvpRule& avpRule) {
84 9639 : const Format* format = getFormat();
85 :
86 9639 : if (format->isGrouped()) {
87 9638 : if (avpRule.isFixed()) {
88 730 : if (!allow_fixed_rule_) {
89 : std::string s_ex = ert::tracing::Logger::asString(
90 : "Incorrect position for fixed avp rule '<%s>' within grouped avp '%s'",
91 0 : avpRule.getAvpName().c_str(), getName().c_str());
92 0 : s_ex += ". Fixed avp rules must be located at the beginning";
93 0 : throw std::runtime_error(s_ex);
94 0 : }
95 : } else
96 8908 : allow_fixed_rule_ = false;
97 :
98 : // Restriction for redefinition (at this same level) of two rules for the same avp:
99 9638 : if (isChild(avpRule.getId())) {
100 : std::string s_ex = ert::tracing::Logger::asString(
101 : "Cannot add two rules for avp '%s', at the same level within grouped avp '%s'",
102 1 : avpRule.getAvpName().c_str(), getName().c_str());
103 1 : throw std::runtime_error(s_ex);
104 1 : }
105 :
106 9637 : avprules_[avprule_position_++] = avpRule;
107 : } else
108 1 : throw std::runtime_error("Cannot add Avp rule on non-grouped Avp");
109 9637 : }
110 :
111 1 : nlohmann::json Avp::asJson(void) const {
112 1 : nlohmann::json result;
113 :
114 1 : result["name"] = name_;
115 1 : result["code"] = id_.first;
116 1 : if (id_.second != 0) result["vendor-name"] = vendor_name_;
117 1 : if (v_bit_) result["v-bit"] = v_bit_;
118 1 : if (m_bit_) result["m-bit"] = m_bit_;
119 :
120 1 : const Format* format = getFormat();
121 :
122 1 : if (format->isGrouped()) {
123 : // Build rules array:
124 0 : nlohmann::json aux;
125 0 : for (const auto& it : avprules_) aux.push_back(it.second.asJson());
126 :
127 0 : result["grouped"]["avprule"] = aux;
128 :
129 0 : } else {
130 1 : result["single"]["format"] = format_name_;
131 :
132 1 : if (format->isEnumerated()) {
133 1 : std::string enums = getEnums();
134 1 : if (enums != "") result["single"]["enum"] = enums;
135 1 : }
136 :
137 1 : if (hasAliases()) {
138 : // Build labels array:
139 1 : nlohmann::json aux, labelJson;
140 6 : for (const auto& it : labels_) {
141 5 : labelJson["data"] = it.first;
142 5 : labelJson["alias"] = it.second;
143 5 : aux.push_back(labelJson);
144 : }
145 1 : result["single"]["label"] = aux;
146 1 : }
147 : }
148 :
149 1 : return result;
150 0 : }
151 :
152 : } // namespace stack
153 : } // namespace diametercodec
154 : } // namespace ert
|