json_codec.cc 17.4 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
  
  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;
    }
  }
59
60
  loggers::get_instance().log("json_codec::decode: decode_str=%s", it->second.c_str());

Yann Garcia's avatar
Yann Garcia committed
61
62
63
64
65
66
67
  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
68
  loggers::get_instance().log("json_codec::decode: decoding_buffer=%s", str.c_str());
Yann Garcia's avatar
Yann Garcia committed
69
  TTCN_Buffer decoding_buffer(OCTETSTRING(str.length(), (const unsigned char*)str.c_str()));
Yann Garcia's avatar
Yann Garcia committed
70

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

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


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


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