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 :
42 : // Project
43 : #include <ert/tracing/Logger.hpp>
44 : #include <ert/diametercodec/stack/Dictionary.hpp>
45 : #include <ert/diametercodec/stack/Avp.hpp>
46 : #include <ert/diametercodec/stack/Format.hpp>
47 :
48 :
49 : namespace ert
50 : {
51 : namespace diametercodec
52 : {
53 : namespace stack
54 : {
55 :
56 10053 : bool Avp::isChild(const core::AvpId & avpId) const {
57 10053 : const Format * format = getFormat();
58 :
59 10053 : if(!format->isGrouped()) return false;
60 :
61 43231 : for(auto it: avprules_)
62 33480 : if(avpId == (it.second.getId()))
63 33480 : return true;
64 :
65 9751 : return false;
66 : }
67 :
68 69308 : const Format * Avp::getFormat() const {
69 69308 : return dictionary_->getFormat(format_name_);
70 : }
71 :
72 :
73 3625 : void Avp::addLabel(const std::string & data, const std::string & alias) {
74 3625 : const Format * format = getFormat();
75 :
76 3625 : if(format->isGrouped())
77 0 : throw std::runtime_error("Cannot add 'data-alias' entry on a grouped Avp");
78 : else
79 3625 : labels_[data] = alias;
80 :
81 3625 : LOGWARNING(
82 :
83 : if(format->isEnumerated() && !allowEnum(atoi(data.c_str()))) {
84 : ert::tracing::Logger::warning(ert::tracing::Logger::asString("Makes no sense adding alias '%s' for enum value '%s' out of range ('%s'), Avp '%s'",
85 : alias.c_str(), data.c_str(), getEnums(), name_.c_str()), ERT_FILE_LOCATION);
86 : }
87 : );
88 3625 : }
89 :
90 1653 : void Avp::addAvpRule(const AvpRule & avpRule) {
91 1653 : const Format * format = getFormat();
92 :
93 1653 : if(format->isGrouped()) {
94 1652 : if(avpRule.isFixed()) {
95 125 : if(!allow_fixed_rule_) {
96 0 : std::string s_ex = ert::tracing::Logger::asString("Incorrect position for fixed avp rule '<%s>' within grouped avp '%s'", avpRule.getAvpName().c_str(), getName().c_str());
97 0 : s_ex += ". Fixed avp rules must be located at the beginning";
98 0 : throw std::runtime_error(s_ex);
99 0 : }
100 1527 : } else allow_fixed_rule_ = false;
101 :
102 : // Restriction for redefinition (at this same level) of two rules for the same avp:
103 1652 : if(isChild(avpRule.getId())) {
104 1 : std::string s_ex = ert::tracing::Logger::asString("Cannot add two rules for avp '%s', at the same level within grouped avp '%s'", avpRule.getAvpName().c_str(), getName().c_str());
105 1 : throw std::runtime_error(s_ex);
106 1 : }
107 :
108 1651 : avprules_[avprule_position_++] = avpRule;
109 : } else
110 1 : throw std::runtime_error("Cannot add Avp rule on non-grouped Avp");
111 1651 : }
112 :
113 1 : nlohmann::json Avp::asJson(void) const {
114 1 : nlohmann::json result;
115 :
116 1 : result["name"] = name_;
117 1 : result["code"] = id_.first;
118 1 : if(id_.second != 0) result["vendor-name"] = vendor_name_;
119 1 : if (v_bit_) result["v-bit"] = v_bit_;
120 1 : if (m_bit_) result["m-bit"] = m_bit_;
121 :
122 1 : const Format * format = getFormat();
123 :
124 1 : if(format->isGrouped()) {
125 :
126 : // Build rules array:
127 0 : nlohmann::json aux;
128 0 : for(auto it: avprules_)
129 0 : aux.push_back(it.second.asJson());
130 :
131 0 : result["grouped"]["avprule"] = aux;
132 :
133 0 : } else {
134 1 : result["single"]["format"] = format_name_;
135 :
136 1 : if(format->isEnumerated()) {
137 1 : std::string enums = getEnums();
138 1 : if(enums != "") result["single"]["enum"] = enums;
139 1 : }
140 :
141 1 : if(hasAliases()) {
142 : // Build labels array:
143 1 : nlohmann::json aux, labelJson;
144 6 : for(auto it: labels_) {
145 5 : labelJson["data"] = it.first;
146 5 : labelJson["alias"] = it.second;
147 5 : aux.push_back(labelJson);
148 5 : }
149 1 : result["single"]["label"] = aux;
150 1 : }
151 : }
152 :
153 1 : return result;
154 0 : }
155 :
156 : }
157 : }
158 : }
159 :
|