json_codec.cc 17.3 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("}"));
YannGarcia's avatar
YannGarcia committed
31
32
33
34
  } else if (msg.ischosen(LibItsHttp__JsonMessageBodyTypes::JsonBody::ALT_appContext)) {
    const UEAppInterfaceAPI__TypesAndValues::AppContext& appContext = msg.appContext();
    appContext.encode(UEAppInterfaceAPI__TypesAndValues::AppContext_descr_, encoding_buffer, TTCN_EncDec::CT_JSON);
    data = char2oct(CHARSTRING("{\"AppContext\": ")) + OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) + char2oct(CHARSTRING("}"));
Yann Garcia's avatar
Yann Garcia committed
35
36
37
  } else {
    loggers::get_instance().error("json_codec::encode: Not supported");
  }
Yann Garcia's avatar
Yann Garcia committed
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
64
65
66
  
  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
67
  loggers::get_instance().log("json_codec::decode: decoding_buffer=%s", str.c_str());
Yann Garcia's avatar
Yann Garcia committed
68
  TTCN_Buffer decoding_buffer(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
Yann Garcia's avatar
Yann Garcia committed
69

YannGarcia's avatar
YannGarcia committed
70
71
  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
72
73
74
      LocationAPI__TypesAndValues::UserList user_list;
      user_list.decode(LocationAPI__TypesAndValues::UserList_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
      msg.userList() = user_list;
75
  } else if (it->second.find("\"accessPointList\"") != std::string::npos) { // Be careful to the order
YannGarcia's avatar
YannGarcia committed
76
                                                                              // TODO To be refined, find("\"accessPointList\"") is not optimal
Yann Garcia's avatar
Yann Garcia committed
77
78
79
    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
80
81
  } 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
82
83
84
    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
85
86
87
88
89
  } 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
90
91
92
93
  } 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
94
  } else if (it->second.find("\"userInfo\"") != std::string::npos) {
Yann Garcia's avatar
Yann Garcia committed
95
    LocationAPI__TypesAndValues::UserInfo user_info;
Yann Garcia's avatar
Yann Garcia committed
96
97
    user_info.decode(LocationAPI__TypesAndValues::UserInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.userInfo() = user_info;
Yann Garcia's avatar
Yann Garcia committed
98
99
100
101
  } 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
102
103
104
105
  } 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
106
  } else if (it->second.find("\"CellChangeSubscription\"") != std::string::npos) {
YannGarcia's avatar
YannGarcia committed
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
138
139
140
141
142
//    // 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
143
144
145
146
147
    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) {
YannGarcia's avatar
YannGarcia committed
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
179
180
181
182
183
//    // 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
184
185
186
    RnisAPI__TypesAndValues::RabInfo rab_info;
    rab_info.decode(RnisAPI__TypesAndValues::RabInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.rabInfo() = rab_info;
187
  } else if (it->second.find("\"S1BearerInfo\"") != std::string::npos) {
YannGarcia's avatar
YannGarcia committed
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
222
223
//    // 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()));
224
225
226
    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
227
228
229
230
  } 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;
231
232
233
234
235
236
237
238
239
240
241
242
  } else if (it->second.find("\"RabEstSubscription\"") != std::string::npos) {
    RnisAPI__TypesAndValues::RabEstSubscription rab_est_subscription;
    rab_est_subscription.decode(RnisAPI__TypesAndValues::RabEstSubscription_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.rabEstSubscription() = rab_est_subscription;
  } else if (it->second.find("\"RabModSubscription\"") != std::string::npos) {
    RnisAPI__TypesAndValues::RabModSubscription rab_mod_subscription;
    rab_mod_subscription.decode(RnisAPI__TypesAndValues::RabModSubscription_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.rabModSubscription() = rab_mod_subscription;
  } else if (it->second.find("\"RabRelSubscription\"") != std::string::npos) {
    RnisAPI__TypesAndValues::RabRelSubscription rab_rel_subscription;
    rab_rel_subscription.decode(RnisAPI__TypesAndValues::RabRelSubscription_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.rabRelSubscription() = rab_rel_subscription;
YannGarcia's avatar
YannGarcia committed
243
244
245
246
247
248
249
250
  } else if (it->second.find("\"AppContext\"") != std::string::npos) {
    UEAppInterfaceAPI__TypesAndValues::AppContext appContext;
    appContext.decode(UEAppInterfaceAPI__TypesAndValues::AppContext_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.appContext() = appContext;
  } else if (it->second.find("\"AppInfo\"") != std::string::npos) {
    UEAppInterfaceAPI__TypesAndValues::AppInfo appInfo;
    appInfo.decode(UEAppInterfaceAPI__TypesAndValues::AppInfo_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
    msg.appInfo() = appInfo;
YannGarcia's avatar
YannGarcia committed
251
252
  } else if (it->second.find("\"bwInfo\"") != std::string::npos) {
    BwManagementAPI__TypesAndValues::BwInfo bw_info;
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

    // 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
269
    msg.bwInfo() = bw_info;
270
  } else if (it->second.find("\"problemDetails\"") != std::string::npos) { // TODO To be refined, problemDetails in different modules
YannGarcia's avatar
YannGarcia committed
271
272
273
274
275
276
277
278


//    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);
279
    msg.problemDetails__rnis() = problem_details;
YannGarcia's avatar
YannGarcia committed
280
281


Yann Garcia's avatar
Yann Garcia committed
282
283
284
285
286
287
288
289
290
291
  } 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;