json_codec.cc 15.1 KB
Newer Older
Yann Garcia's avatar
Yann Garcia committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdexcept>
#include <regex>
#include <string>

#include "json_codec_factory.hh"

#include "loggers.hh"

#include "LibItsHttp_JsonMessageBodyTypes.hh"

int json_codec::encode (const LibItsHttp__JsonMessageBodyTypes::JsonBody& msg, OCTETSTRING& data)
{
  loggers::get_instance().log_msg(">>> json_codec::encode: ", (const Base_Type&)msg);

  TTCN_EncDec::clear_error();
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
  TTCN_Buffer encoding_buffer;
Yann Garcia's avatar
Yann Garcia committed
18
19
20
21
22

  if (msg.ischosen(LibItsHttp__JsonMessageBodyTypes::JsonBody::ALT_ueIdentityTagInfo)) {
    const UEidentityAPI__TypesAndValues::UeIdentityTagInfo& ue_identity_tag_info = msg.ueIdentityTagInfo();
    ue_identity_tag_info.encode(UEidentityAPI__TypesAndValues::UeIdentityTagInfo_descr_, encoding_buffer, TTCN_EncDec::CT_JSON);
    data = OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data());
YannGarcia's avatar
YannGarcia committed
23
24
25
26
  } else if (msg.ischosen(LibItsHttp__JsonMessageBodyTypes::JsonBody::ALT_userTrackingSubscription)) {
    const LocationAPI__TypesAndValues::UserTrackingSubscription& user_tracking_subscription = msg.userTrackingSubscription();
    user_tracking_subscription.encode(LocationAPI__TypesAndValues::UserTrackingSubscription_descr_, encoding_buffer, TTCN_EncDec::CT_JSON);
    data = char2oct(CHARSTRING("{\"userTrackingSubscription\": ")) + OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) + char2oct(CHARSTRING("}"));
YannGarcia's avatar
YannGarcia committed
27
28
29
30
  } else if (msg.ischosen(LibItsHttp__JsonMessageBodyTypes::JsonBody::ALT_cellChangeSubscription)) {
    const RnisAPI__TypesAndValues::CellChangeSubscription& cell_change_subscription = msg.cellChangeSubscription();
    cell_change_subscription.encode(RnisAPI__TypesAndValues::CellChangeSubscription_descr_, encoding_buffer, TTCN_EncDec::CT_JSON);
    data = char2oct(CHARSTRING("{\"CellChangeSubscription\": ")) + OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) + char2oct(CHARSTRING("}"));
Yann Garcia's avatar
Yann Garcia committed
31
32
33
  } else {
    loggers::get_instance().error("json_codec::encode: Not supported");
  }
Yann Garcia's avatar
Yann Garcia committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  
  loggers::get_instance().log("<<< json_codec::encode");
  return 0;
}

int json_codec::decode (const OCTETSTRING& p_data, LibItsHttp__JsonMessageBodyTypes::JsonBody& msg, params* p_params)
{
  loggers::get_instance().log_msg(">>> json_codec::decode: p_data=", p_data);

  // Sanity checks
  params::const_iterator it;
  if (p_params == nullptr) {
    loggers::get_instance().warning("json_codec::decode: Failed to access p_params (null pointer)");
    return -1;
  } else {
    it = p_params->find("decode_str");
    if (it == p_params->cend()) {
      loggers::get_instance().warning("json_codec::decode: Failed to access p_params item (decode_str)");
      return -1;
    }
  }
  
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
  TTCN_EncDec::clear_error();
  // Remove data structure name...
  int idx_begin = it->second.find(":");
  int idx_end = it->second.rfind("}") - 1; // Remove the last '}'
  std::string str = it->second.substr(idx_begin + 1, idx_end - idx_begin);
  // ..and create the decoding buffer
  TTCN_Buffer decoding_buffer(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
Yann Garcia's avatar
Yann Garcia committed
64

YannGarcia's avatar
YannGarcia committed
65
66
  if (it->second.find("\"userList\"") != std::string::npos) { // Be careful to the order
                                                              // TODO To be refined, find("\"userList\"") is not optimal
Yann Garcia's avatar
Yann Garcia committed
67
68
69
      LocationAPI__TypesAndValues::UserList user_list;
      user_list.decode(LocationAPI__TypesAndValues::UserList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
      msg.userList() = user_list;
YannGarcia's avatar
YannGarcia committed
70
71
    } else if (it->second.find("\"accessPointList\"") != std::string::npos) { // Be careful to the order
                                                                              // TODO To be refined, find("\"accessPointList\"") is not optimal
Yann Garcia's avatar
Yann Garcia committed
72
73
74
    LocationAPI__TypesAndValues::AccessPointList access_point_list;
    access_point_list.decode(LocationAPI__TypesAndValues::AccessPointList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.accessPointList() = access_point_list;
YannGarcia's avatar
YannGarcia committed
75
76
  } else if (it->second.find("\"SubscriptionLinkList\"") != std::string::npos) { // Be careful to the order
                                                                                 // TODO To be refined, find("\"accessPointList\"") is not optimal
YannGarcia's avatar
YannGarcia committed
77
78
79
    RnisAPI__TypesAndValues::SubscriptionLinkList subscription_link_list;
    subscription_link_list.decode(RnisAPI__TypesAndValues::SubscriptionLinkList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.subscriptionLinkList() = subscription_link_list;
YannGarcia's avatar
YannGarcia committed
80
81
82
83
84
  } else if (it->second.find("\"transportInfoList\"") != std::string::npos) { // Be careful to the order
                                                                              // TODO To be refined, find("\"accessPointList\"") is not optimal
    AppEnablementAPI__TypesAndValues::TransportInfoList transport_info_list;
    transport_info_list.decode(AppEnablementAPI__TypesAndValues::TransportInfoList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.transportInfoList() = transport_info_list;
YannGarcia's avatar
YannGarcia committed
85
86
87
88
  } else if (it->second.find("\"userTrackingSubscription\"") != std::string::npos) {
    LocationAPI__TypesAndValues::UserTrackingSubscription user_tracking_subscription;
    user_tracking_subscription.decode(LocationAPI__TypesAndValues::UserTrackingSubscription_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.userTrackingSubscription() = user_tracking_subscription;
Yann Garcia's avatar
Yann Garcia committed
89
  } else if (it->second.find("\"userInfo\"") != std::string::npos) {
Yann Garcia's avatar
Yann Garcia committed
90
    LocationAPI__TypesAndValues::UserInfo user_info;
Yann Garcia's avatar
Yann Garcia committed
91
92
    user_info.decode(LocationAPI__TypesAndValues::UserInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.userInfo() = user_info;
Yann Garcia's avatar
Yann Garcia committed
93
94
95
96
  } else if (it->second.find("\"ueIdentityTagInfo\"") != std::string::npos) {
    UEidentityAPI__TypesAndValues::UeIdentityTagInfo ue_identity_tag_info;
    ue_identity_tag_info.decode(UEidentityAPI__TypesAndValues::UeIdentityTagInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.ueIdentityTagInfo() = ue_identity_tag_info;
YannGarcia's avatar
YannGarcia committed
97
98
99
100
  } else if (it->second.find("\"trafficRule\"") != std::string::npos) {
    AppEnablementAPI__TypesAndValues::TrafficRule traffic_rule;
    traffic_rule.decode(AppEnablementAPI__TypesAndValues::TrafficRule_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.trafficRule() = traffic_rule;
YannGarcia's avatar
YannGarcia committed
101
  } else if (it->second.find("\"CellChangeSubscription\"") != std::string::npos) {
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    // Replace "type": "1" by type": "EU_IPV4_ADDRESS", "type": "2"...
    // TODO Create a method instead of copy/past
    //loggers::get_instance().log("json_codec::decode: Before, str=%s", str.c_str());
    std::size_t it_start = str.find("\"type\"");
    loggers::get_instance().log("json_codec::decode: id_start=%d", it_start);
    if (it_start != std::string::npos) {
      std::size_t it_stop = str.find(",", it_start);
      //loggers::get_instance().log("json_codec::decode: id_stop=%d", it_stop);
      //loggers::get_instance().log("json_codec::decode: segment=%s", str.substr(it_start, it_stop - it_start).c_str());
      std::size_t it = str.find("1", it_start, 1);
      //loggers::get_instance().log("json_codec::decode: it=%d", it);
      if ((it != std::string::npos) && (it < it_stop)) {
        str = str.substr(0, it) + "UE_IPV4_ADDRESS" + str.substr(it + 1);
      } else {
        it = str.find("2", it_start, 1);
        //loggers::get_instance().log("json_codec::decode: it=%d", it);
        if ((it != std::string::npos) && (it < it_stop)) {
          str = str.substr(0, it) + "UE_IPV6_ADDRESS" + str.substr(it + 1);
        } else {
          it = str.find("3", it_start, 1);
          //loggers::get_instance().log("json_codec::decode: it=%d", it);
          if ((it != std::string::npos) && (it < it_stop)) {
            str = str.substr(0, it) + "NATED_IP_ADDRESS" + str.substr(it + 1);
          } else {
            it = str.find("4", it_start, 1);
            //loggers::get_instance().log("json_codec::decode: it=%d", it);
            if ((it != std::string::npos) && (it < it_stop)) {
              str = str.substr(0, it) + "GTP_TEID" + str.substr(it + 1);
            }
          }
        }
      }
    }
    //loggers::get_instance().log("json_codec::decode: After, str=%s", str.c_str());
    decoding_buffer.clear();
    decoding_buffer.put_os(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
YannGarcia's avatar
YannGarcia committed
138
139
140
141
142
    RnisAPI__TypesAndValues::CellChangeSubscription cell_change_subscription;
    cell_change_subscription.decode(RnisAPI__TypesAndValues::CellChangeSubscription_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.cellChangeSubscription() = cell_change_subscription;
    //TODO Continue with other ChangeSubscription
  } else if (it->second.find("\"RabInfo\"") != std::string::npos) {
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    // Replace "type": "1" by type": "EU_IPV4_ADDRESS", "type": "2"...
    // TODO Create a method instead of copy/past
    // loggers::get_instance().log("json_codec::decode: Before, str=%s", str.c_str());
    std::size_t it_start = str.find("\"type\"");
    loggers::get_instance().log("json_codec::decode: id_start=%d", it_start);
    if (it_start != std::string::npos) {
      std::size_t it_stop = str.find(",", it_start);
      //loggers::get_instance().log("json_codec::decode: id_stop=%d", it_stop);
      //loggers::get_instance().log("json_codec::decode: segment=%s", str.substr(it_start, it_stop - it_start).c_str());
      std::size_t it = str.find("1", it_start, 1);
      //loggers::get_instance().log("json_codec::decode: it=%d", it);
      if ((it != std::string::npos) && (it < it_stop)) {
        str = str.substr(0, it) + "UE_IPV4_ADDRESS" + str.substr(it + 1);
      } else {
        it = str.find("2", it_start, 1);
        //loggers::get_instance().log("json_codec::decode: it=%d", it);
        if ((it != std::string::npos) && (it < it_stop)) {
          str = str.substr(0, it) + "UE_IPV6_ADDRESS" + str.substr(it + 1);
        } else {
          it = str.find("3", it_start, 1);
          //loggers::get_instance().log("json_codec::decode: it=%d", it);
          if ((it != std::string::npos) && (it < it_stop)) {
            str = str.substr(0, it) + "NATED_IP_ADDRESS" + str.substr(it + 1);
          } else {
            it = str.find("4", it_start, 1);
            //loggers::get_instance().log("json_codec::decode: it=%d", it);
            if ((it != std::string::npos) && (it < it_stop)) {
              str = str.substr(0, it) + "GTP_TEID" + str.substr(it + 1);
            }
          }
        }
      }
    }
    //loggers::get_instance().log("json_codec::decode: After, str=%s", str.c_str());
    decoding_buffer.clear();
    decoding_buffer.put_os(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
YannGarcia's avatar
YannGarcia committed
179
180
181
    RnisAPI__TypesAndValues::RabInfo rab_info;
    rab_info.decode(RnisAPI__TypesAndValues::RabInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.rabInfo() = rab_info;
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  } else if (it->second.find("\"S1BearerInfo\"") != std::string::npos) {
    // Replace "type": "1" by type": "EU_IPV4_ADDRESS", "type": "2"...
    // TODO Create a method instead of copy/past
    // loggers::get_instance().log("json_codec::decode: Before, str=%s", str.c_str());
    std::size_t it_start = str.find("\"type\"");
    loggers::get_instance().log("json_codec::decode: id_start=%d", it_start);
    if (it_start != std::string::npos) {
      std::size_t it_stop = str.find(",", it_start);
      //loggers::get_instance().log("json_codec::decode: id_stop=%d", it_stop);
      //loggers::get_instance().log("json_codec::decode: segment=%s", str.substr(it_start, it_stop - it_start).c_str());
      std::size_t it = str.find("1", it_start, 1);
      //loggers::get_instance().log("json_codec::decode: it=%d", it);
      if ((it != std::string::npos) && (it < it_stop)) {
        str = str.substr(0, it) + "UE_IPV4_ADDRESS" + str.substr(it + 1);
      } else {
        it = str.find("2", it_start, 1);
        //loggers::get_instance().log("json_codec::decode: it=%d", it);
        if ((it != std::string::npos) && (it < it_stop)) {
          str = str.substr(0, it) + "UE_IPV6_ADDRESS" + str.substr(it + 1);
        } else {
          it = str.find("3", it_start, 1);
          //loggers::get_instance().log("json_codec::decode: it=%d", it);
          if ((it != std::string::npos) && (it < it_stop)) {
            str = str.substr(0, it) + "NATED_IP_ADDRESS" + str.substr(it + 1);
          } else {
            it = str.find("4", it_start, 1);
            //loggers::get_instance().log("json_codec::decode: it=%d", it);
            if ((it != std::string::npos) && (it < it_stop)) {
              str = str.substr(0, it) + "GTP_TEID" + str.substr(it + 1);
            }
          }
        }
      }
    }
    //loggers::get_instance().log("json_codec::decode: After, str=%s", str.c_str());
    decoding_buffer.clear();
    decoding_buffer.put_os(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
    RnisAPI__TypesAndValues::S1BearerInfo s1_nearer_info;
    s1_nearer_info.decode(RnisAPI__TypesAndValues::S1BearerInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.s1BearerInfo() = s1_nearer_info;
YannGarcia's avatar
YannGarcia committed
222
223
224
225
  } else if (it->second.find("\"PlmnInfo\"") != std::string::npos) {
    RnisAPI__TypesAndValues::PlmnInfo plmn_info;
    plmn_info.decode(RnisAPI__TypesAndValues::PlmnInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.plmnInfo() = plmn_info;
YannGarcia's avatar
YannGarcia committed
226
227
  } else if (it->second.find("\"bwInfo\"") != std::string::npos) {
    BwManagementAPI__TypesAndValues::BwInfo bw_info;
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

    // Need to change some enumerated string not supported by TTCN-3 language
    if (str.find("not defined in the present document") != std::string::npos) {
      str = regex_replace(str, regex("not defined in the present document"), "not_defined_in_the_present_document");
    }
    if (str.find("00 = Downlink (towards the UE)") != std::string::npos) {
      str = regex_replace(str, regex("00 = Downlink \\(towards the UE\\)"), "Downlink");
    } else if (str.find("01 = Uplink (towards the application/session)") != std::string::npos) {
      str = regex_replace(str, regex("01 = Uplink \\(towards the application\\/session\\)"), "Uplink");
    } else if (str.find("10 = Symmetrical") != std::string::npos) {
      str = regex_replace(str, regex("10 = Symmetrical"), "Symmetrical");
    }
    //loggers::get_instance().log("json_codec::decode: ##########; %s", str.c_str());

    TTCN_Buffer decoding_buffer_(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
    bw_info.decode(BwManagementAPI__TypesAndValues::BwInfo_descr_, decoding_buffer_, TTCN_EncDec::CT_JSON);
YannGarcia's avatar
YannGarcia committed
244
    msg.bwInfo() = bw_info;
245
  } else if (it->second.find("\"problemDetails\"") != std::string::npos) { // TODO To be refined, problemDetails in different modules
YannGarcia's avatar
YannGarcia committed
246
247
248
249
250
251
252
253


//    UEidentityAPI__TypesAndValues::ProblemDetails problem_details;
//    problem_details.decode(UEidentityAPI__TypesAndValues::ProblemDetails_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
//    msg.problemDetails__ue__identity() = problem_details;

    RnisAPI__TypesAndValues::ProblemDetails problem_details;
    problem_details.decode(RnisAPI__TypesAndValues::ProblemDetails_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
254
    msg.problemDetails__rnis() = problem_details;
YannGarcia's avatar
YannGarcia committed
255
256


Yann Garcia's avatar
Yann Garcia committed
257
258
259
260
261
262
263
264
265
266
  } else {
    loggers::get_instance().warning("json_codec::decode: Unsupported variant");
    return -1;
  }
  
  loggers::get_instance().log_msg("<<< json_codec::decode: ", (const Base_Type&)msg);
  return 0;
}

json_codec_factory json_codec_factory::_f;