Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 1 | #include "mncc.h" |
| 2 | #include "MNCC_Types.hh" |
| 3 | |
| 4 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
| 5 | |
| 6 | namespace MNCC__Types { |
| 7 | |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 8 | static int mncc_sock_version = MNCC_SOCK_VERSION; |
| 9 | |
| 10 | BOOLEAN set__MNCC__version(INTEGER const& version) |
| 11 | { |
Vadim Yanitskiy | 9ff4780 | 2021-10-28 14:55:58 +0300 | [diff] [blame] | 12 | if (version != 7 && version != 8) |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 13 | return false; |
| 14 | mncc_sock_version = version; |
| 15 | return true; |
| 16 | } |
| 17 | |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 18 | static void enc_bcap(struct gsm_mncc_bearer_cap *out, const MNCC__bearer__cap& in) |
| 19 | { |
| 20 | out->transfer = in.transfer(); |
| 21 | out->mode = in.mode(); |
| 22 | out->coding = in.coding(); |
| 23 | out->radio = in.radio(); |
| 24 | out->speech_ctm = in.speech__ctm(); |
| 25 | |
| 26 | for (int i = 0; i < in.speech__ver().lengthof(); i++) |
| 27 | out->speech_ver[i] = in.speech__ver()[i]; |
| 28 | |
| 29 | if (in.data().is_value()) { |
| 30 | MNCC__bearer__cap__data data = in.data(); |
| 31 | out->data.rate_adaption = (gsm48_bcap_ra) (int) data.rate__adaptation(); |
| 32 | out->data.sig_access = (gsm48_bcap_sig_access) (int) data.sig__access(); |
| 33 | out->data.async = data.async(); |
| 34 | out->data.nr_stop_bits = data.nr__stop__bits(); |
| 35 | out->data.nr_data_bits = data.nr__data__bits(); |
| 36 | out->data.user_rate = (gsm48_bcap_user_rate) (int) data.user__rate(); |
| 37 | out->data.parity = (gsm48_bcap_parity) (int) data.parity(); |
| 38 | out->data.interm_rate = (gsm48_bcap_interm_rate) (int) data.interm__rate(); |
| 39 | out->data.transp = (gsm48_bcap_transp) (int) data.transp(); |
| 40 | out->data.modem_type = (gsm48_bcap_modem_type) (int) data.modem__type(); |
| 41 | } |
| 42 | |
| 43 | } |
| 44 | |
| 45 | static MNCC__bearer__cap dec_bcap(const struct gsm_mncc_bearer_cap *in) |
| 46 | { |
| 47 | MNCC__bearer__cap__data data; |
| 48 | MNCC__speech__vers vers; |
| 49 | data = MNCC__bearer__cap__data((GSM48__bcap__ra) in->data.rate_adaption, |
| 50 | (GSM48__bcap__sig__access) in->data.sig_access, |
| 51 | in->data.async, |
| 52 | in->data.nr_stop_bits, |
| 53 | in->data.nr_data_bits, |
| 54 | (GSM48__bcap__user__rate) in->data.user_rate, |
| 55 | (GSM48__bcap__parity) in->data.parity, |
| 56 | (GSM48__bcap__interm__rate) in->data.interm_rate, |
| 57 | (GSM48__bcap__transp) in->data.transp, |
| 58 | (GSM48__bcap__modem__type) in->data.modem_type); |
| 59 | |
Harald Welte | 0556600 | 2018-03-26 20:52:45 +0200 | [diff] [blame] | 60 | for (unsigned int i = 0; i < ARRAY_SIZE(in->speech_ver); i++) { |
| 61 | vers[i] = in->speech_ver[i]; |
| 62 | if (vers[i] == -1) |
| 63 | break; |
| 64 | } |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 65 | |
| 66 | return MNCC__bearer__cap(in->transfer, in->mode, in->coding, in->radio, in->speech_ctm, |
| 67 | vers, data); |
| 68 | } |
| 69 | |
| 70 | |
| 71 | static void enc_number(struct gsm_mncc_number *num, const MNCC__number& in) |
| 72 | { |
| 73 | num->type = in.number__type(); |
| 74 | num->plan = in.plan(); |
| 75 | num->present = in.presence(); |
| 76 | num->screen = in.screen(); |
| 77 | strncpy(num->number, in.number(), sizeof(num->number)); |
| 78 | } |
| 79 | |
| 80 | static MNCC__number dec_number(const struct gsm_mncc_number *num) |
| 81 | { |
| 82 | return MNCC__number(num->type, num->plan,num->present, num->screen, num->number); |
| 83 | } |
| 84 | |
| 85 | OCTETSTRING enc__MNCC__PDU(const MNCC__PDU& in) |
| 86 | { |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 87 | struct gsm_mncc mncc; |
| 88 | OCTETSTRING ret_val; |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 89 | TTCN_Buffer ttcn_buffer; |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 90 | |
| 91 | memset(&mncc, 0, sizeof(mncc)); |
| 92 | mncc.msg_type = in.msg__type(); |
| 93 | |
Harald Welte | 1823cb1 | 2018-02-11 11:39:29 +0100 | [diff] [blame] | 94 | switch (in.u().get_selection()) { |
| 95 | case MNCC__MsgUnion::ALT_signal: { |
| 96 | const MNCC__PDU__Signal& in_sig = in.u().signal(); |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 97 | mncc.callref = in_sig.callref(); |
| 98 | if (in_sig.bearer__cap().is_value()) { |
| 99 | enc_bcap(&mncc.bearer_cap, in_sig.bearer__cap()); |
| 100 | mncc.fields |= MNCC_F_BEARER_CAP; |
| 101 | } |
| 102 | if (in_sig.called().is_value()) { |
| 103 | enc_number(&mncc.called, in_sig.called()); |
| 104 | mncc.fields |= MNCC_F_CALLED; |
| 105 | } |
| 106 | if (in_sig.calling().is_value()) { |
| 107 | enc_number(&mncc.calling, in_sig.calling()); |
| 108 | mncc.fields |= MNCC_F_CALLING; |
| 109 | } |
| 110 | if (in_sig.redirecting().is_value()) { |
| 111 | enc_number(&mncc.redirecting, in_sig.redirecting()); |
| 112 | mncc.fields |= MNCC_F_REDIRECTING; |
| 113 | } |
| 114 | if (in_sig.connected().is_value()) { |
| 115 | enc_number(&mncc.connected, in_sig.connected()); |
| 116 | mncc.fields |= MNCC_F_CONNECTED; |
| 117 | } |
| 118 | if (in_sig.cause().is_value()) { |
| 119 | const MNCC__cause &cause = in_sig.cause(); |
| 120 | TTCN_Buffer ttcn_buffer(cause.diag()); |
| 121 | mncc.cause.location = cause.location(); |
| 122 | mncc.cause.coding = cause.coding(); |
| 123 | mncc.cause.rec = cause.rec(); |
| 124 | mncc.cause.rec_val = cause.rec__val(); |
| 125 | mncc.cause.value = cause.val(); |
| 126 | mncc.cause.diag_len = ttcn_buffer.get_len(); |
| 127 | if (mncc.cause.diag_len > (int) sizeof(mncc.cause.diag)) { |
| 128 | TTCN_error("MNCC diagnostics length %u too long", mncc.cause.diag_len); |
| 129 | mncc.cause.diag_len = sizeof(mncc.cause.diag); |
| 130 | } |
| 131 | memcpy(mncc.cause.diag, ttcn_buffer.get_data(), ttcn_buffer.get_len()); |
| 132 | mncc.fields |= MNCC_F_CAUSE; |
| 133 | } |
| 134 | if (in_sig.progress().is_value()) { |
| 135 | const MNCC__progress &progress = in_sig.progress(); |
| 136 | mncc.progress.coding = progress.coding(); |
| 137 | mncc.progress.location = progress.location(); |
| 138 | mncc.progress.descr = progress.descr(); |
| 139 | mncc.fields |= MNCC_F_PROGRESS; |
| 140 | } |
| 141 | if (in_sig.useruser().is_value()) { |
| 142 | const MNCC__useruser &useruser = in_sig.useruser(); |
| 143 | mncc.useruser.proto = useruser.proto(); |
| 144 | strncpy(mncc.useruser.info, useruser.info(), sizeof(mncc.useruser.info)); |
| 145 | mncc.fields |= MNCC_F_USERUSER; |
| 146 | } |
| 147 | if (in_sig.facility().is_value()) { |
| 148 | const CHARSTRING &fac = in_sig.facility(); |
| 149 | strncpy(mncc.facility.info, fac, sizeof(mncc.facility.info)); |
| 150 | mncc.facility.len = strlen(mncc.facility.info); |
| 151 | mncc.fields |= MNCC_F_FACILITY; |
| 152 | } |
| 153 | if (in_sig.cccap().is_value()) { |
| 154 | const MNCC__cccap &cccap = in_sig.cccap(); |
| 155 | mncc.cccap.dtmf = cccap.dtmf(); |
| 156 | mncc.cccap.pcp = cccap.pcp(); |
| 157 | mncc.fields |= MNCC_F_CCCAP; |
| 158 | } |
| 159 | if (in_sig.ssversion().is_value()) { |
| 160 | const CHARSTRING &ssv = in_sig.ssversion(); |
| 161 | strncpy(mncc.ssversion.info, ssv, sizeof(mncc.ssversion.info)); |
| 162 | mncc.ssversion.len = strlen(mncc.ssversion.info); |
| 163 | mncc.fields |= MNCC_F_SSVERSION; |
| 164 | } |
| 165 | mncc.clir.sup = in_sig.clir__sup(); |
| 166 | mncc.clir.inv = in_sig.clir__inv(); |
| 167 | if (in_sig.signal().is_value()) { |
| 168 | const INTEGER &sig = in_sig.signal(); |
| 169 | mncc.signal = sig; |
| 170 | mncc.fields |= MNCC_F_SIGNAL; |
| 171 | } |
| 172 | if (in_sig.keypad().is_value()) { |
Harald Welte | d13700d | 2018-02-02 20:06:52 +0100 | [diff] [blame] | 173 | const CHARSTRING &kpd = in_sig.keypad(); |
| 174 | mncc.signal = (int) kpd[0].get_char(); |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 175 | mncc.fields |= MNCC_F_KEYPAD; |
| 176 | } |
| 177 | mncc.more = in_sig.more(); |
| 178 | mncc.notify = in_sig.notify(); |
| 179 | if (in_sig.emergency().is_value()) { |
| 180 | const INTEGER &emerg = in_sig.emergency(); |
| 181 | mncc.emergency = emerg; |
| 182 | mncc.fields |= MNCC_F_EMERGENCY; |
| 183 | } |
| 184 | strncpy(mncc.imsi, in_sig.imsi(), sizeof(mncc.imsi)); |
| 185 | mncc.lchan_type = in_sig.lchan__type(); |
| 186 | mncc.lchan_mode = in_sig.lchan__mode(); |
Vadim Yanitskiy | 9ff4780 | 2021-10-28 14:55:58 +0300 | [diff] [blame] | 187 | if (in_sig.gcr().is_value()) { |
| 188 | const OCTETSTRING &gcr = in_sig.gcr(); |
| 189 | if (mncc_sock_version < 8) |
| 190 | TTCN_error("GCR is only available since MNCCv8"); |
| 191 | memcpy(&mncc.v8.gcr[0], gcr, sizeof(mncc.v8.gcr)); |
| 192 | mncc.fields |= MNCC_F_GCR; |
| 193 | } |
Vadim Yanitskiy | d376063 | 2021-10-28 14:41:41 +0300 | [diff] [blame] | 194 | if (in_sig.sdp().is_value()) { |
| 195 | const CHARSTRING &sdp = in_sig.sdp(); |
Vadim Yanitskiy | 9ff4780 | 2021-10-28 14:55:58 +0300 | [diff] [blame] | 196 | if (mncc_sock_version > 7) |
| 197 | strncpy(&mncc.v8.sdp[0], sdp, sizeof(mncc.v8.sdp)); |
| 198 | else |
| 199 | strncpy(&mncc.v7.sdp[0], sdp, sizeof(mncc.v7.sdp)); |
Vadim Yanitskiy | d376063 | 2021-10-28 14:41:41 +0300 | [diff] [blame] | 200 | } |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 201 | ret_val = OCTETSTRING(sizeof(mncc), (uint8_t *)&mncc); |
Harald Welte | 1823cb1 | 2018-02-11 11:39:29 +0100 | [diff] [blame] | 202 | } |
| 203 | break; |
| 204 | case MNCC__MsgUnion::ALT_data: |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 205 | struct gsm_data_frame data; |
| 206 | memset(&data, 0, sizeof(data)); |
| 207 | data.msg_type = in.msg__type(); |
| 208 | ret_val = OCTETSTRING(sizeof(data), (uint8_t *)&data); |
| 209 | ret_val = ret_val & in.u().data().data(); |
Harald Welte | 1823cb1 | 2018-02-11 11:39:29 +0100 | [diff] [blame] | 210 | break; |
| 211 | case MNCC__MsgUnion::ALT_rtp: |
Vadim Yanitskiy | aff226f | 2021-10-27 14:34:08 +0300 | [diff] [blame] | 212 | struct gsm_mncc_rtp rtp; |
| 213 | memset(&rtp, 0, sizeof(rtp)); |
| 214 | rtp.msg_type = in.msg__type(); |
| 215 | rtp.callref = in.u().rtp().callref(); |
| 216 | ttcn_buffer.put_string(in.u().rtp().ip()); |
| 217 | if (in.u().rtp().is__ipv6()) { |
| 218 | // if(in.u().rtp().ip().lengthof() != 16) print error |
| 219 | rtp.addr.ss_family = AF_INET6; |
| 220 | memcpy(&((struct sockaddr_in6*)&rtp.addr)->sin6_addr, ttcn_buffer.get_data(), |
| 221 | sizeof(struct in6_addr)); |
| 222 | ((struct sockaddr_in6*)&rtp.addr)->sin6_port = htons(in.u().rtp().rtp__port()); |
| 223 | } else { |
| 224 | // if(in.u().rtp().ip().lengthof() != 4) print error |
| 225 | rtp.addr.ss_family = AF_INET; |
| 226 | memcpy(&((struct sockaddr_in*)&rtp.addr)->sin_addr, ttcn_buffer.get_data(), |
| 227 | sizeof(struct in_addr)); |
| 228 | ((struct sockaddr_in*)&rtp.addr)->sin_port = htons(in.u().rtp().rtp__port()); |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 229 | } |
Vadim Yanitskiy | aff226f | 2021-10-27 14:34:08 +0300 | [diff] [blame] | 230 | rtp.payload_type = in.u().rtp().payload__type(); |
| 231 | rtp.payload_msg_type = in.u().rtp().payload__msg__type(); |
| 232 | ret_val = OCTETSTRING(sizeof(rtp), (uint8_t *) &rtp); |
Harald Welte | 1823cb1 | 2018-02-11 11:39:29 +0100 | [diff] [blame] | 233 | break; |
| 234 | case MNCC__MsgUnion::ALT_hello: |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 235 | struct gsm_mncc_hello hello; |
| 236 | memset(&hello, 0, sizeof(hello)); |
| 237 | hello.msg_type = in.msg__type(); |
| 238 | hello.version = in.u().hello().version(); |
| 239 | hello.mncc_size = in.u().hello().mncc__size(); |
| 240 | hello.data_frame_size = in.u().hello().data__frame__size(); |
| 241 | hello.called_offset = in.u().hello().called__offset(); |
| 242 | hello.signal_offset = in.u().hello().signal__offset(); |
| 243 | hello.emergency_offset = in.u().hello().emergency__offset(); |
| 244 | hello.lchan_type_offset = in.u().hello().lchan__type__offset(); |
| 245 | ret_val = OCTETSTRING(sizeof(hello), (uint8_t *) &hello); |
Harald Welte | 1823cb1 | 2018-02-11 11:39:29 +0100 | [diff] [blame] | 246 | break; |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 247 | } |
| 248 | |
| 249 | return ret_val; |
| 250 | } |
| 251 | |
| 252 | MNCC__PDU dec__MNCC__PDU(const OCTETSTRING& in) |
| 253 | { |
| 254 | TTCN_Buffer ttcn_buffer(in); |
| 255 | const struct gsm_mncc *in_mncc; |
| 256 | MNCC__PDU__Signal sign; |
| 257 | const struct gsm_mncc_hello *in_hello; |
| 258 | MNCC__PDU__Hello hello; |
| 259 | const struct gsm_data_frame *in_data; |
| 260 | MNCC__PDU__Data data; |
| 261 | const struct gsm_mncc_rtp *in_rtp; |
| 262 | MNCC__PDU__Rtp rtp; |
| 263 | MNCC__MsgUnion u; |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 264 | bool is_ipv6; |
| 265 | OCTETSTRING ip; |
| 266 | uint16_t port; |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 267 | |
| 268 | in_mncc = (struct gsm_mncc *) ttcn_buffer.get_read_data(); |
| 269 | |
Harald Welte | 8a10e86 | 2018-01-17 13:58:26 +0100 | [diff] [blame] | 270 | sign.set_implicit_omit(); |
| 271 | hello.set_implicit_omit(); |
| 272 | data.set_implicit_omit(); |
| 273 | rtp.set_implicit_omit(); |
| 274 | |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 275 | switch (in_mncc->msg_type) { |
| 276 | case MNCC_SOCKET_HELLO: |
| 277 | in_hello = (const struct gsm_mncc_hello *) in_mncc; |
| 278 | hello = MNCC__PDU__Hello(in_hello->version, |
| 279 | in_hello->mncc_size, |
| 280 | in_hello->data_frame_size, |
| 281 | in_hello->called_offset, |
| 282 | in_hello->signal_offset, |
| 283 | in_hello->emergency_offset, |
| 284 | in_hello->lchan_type_offset); |
| 285 | u.hello() = hello; |
| 286 | break; |
| 287 | case GSM_TCHF_FRAME: |
| 288 | case GSM_TCHF_FRAME_EFR: |
| 289 | case GSM_TCHH_FRAME: |
| 290 | case GSM_TCH_FRAME_AMR: |
| 291 | case GSM_BAD_FRAME: |
| 292 | in_data = (const struct gsm_data_frame *) in_mncc; |
| 293 | u.data() = MNCC__PDU__Data(in_data->callref, |
| 294 | substr(in, offsetof(struct gsm_data_frame, data), |
| 295 | in.lengthof() - offsetof(struct gsm_data_frame, data))); |
| 296 | break; |
| 297 | case MNCC_RTP_CREATE: |
| 298 | case MNCC_RTP_CONNECT: |
| 299 | case MNCC_RTP_FREE: |
Vadim Yanitskiy | aff226f | 2021-10-27 14:34:08 +0300 | [diff] [blame] | 300 | in_rtp = (const struct gsm_mncc_rtp *) in_mncc; |
| 301 | switch (in_rtp->addr.ss_family) { |
| 302 | case AF_INET6: |
| 303 | is_ipv6 = true; |
| 304 | port = ntohs(((struct sockaddr_in6*)&in_rtp->addr)->sin6_port); |
| 305 | ip = OCTETSTRING(sizeof(struct in6_addr), |
| 306 | (const unsigned char*)&((struct sockaddr_in6*)&in_rtp->addr)->sin6_addr); |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 307 | |
| 308 | break; |
Vadim Yanitskiy | aff226f | 2021-10-27 14:34:08 +0300 | [diff] [blame] | 309 | case AF_UNSPEC: //RTP_CREATE and RTP_FREE can contain fully zeroed addr |
| 310 | case AF_INET: |
| 311 | is_ipv6 = false; |
| 312 | port = ntohs(((struct sockaddr_in*)&in_rtp->addr)->sin_port); |
| 313 | ip = OCTETSTRING(sizeof(struct in_addr), |
| 314 | (const unsigned char*)&((struct sockaddr_in*)&in_rtp->addr)->sin_addr); |
Pau Espin Pedrol | 563b3d0 | 2020-09-09 20:19:52 +0200 | [diff] [blame] | 315 | break; |
| 316 | } |
Vadim Yanitskiy | aff226f | 2021-10-27 14:34:08 +0300 | [diff] [blame] | 317 | rtp = MNCC__PDU__Rtp(in_rtp->callref, is_ipv6, ip, port, in_rtp->payload_type, |
| 318 | in_rtp->payload_msg_type, in_rtp->sdp); |
| 319 | u.rtp() = rtp; |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 320 | break; |
| 321 | default: |
| 322 | sign.callref() = in_mncc->callref; |
| 323 | if (in_mncc->fields & MNCC_F_BEARER_CAP) { |
| 324 | sign.bearer__cap() = dec_bcap(&in_mncc->bearer_cap); |
| 325 | } |
| 326 | if (in_mncc->fields & MNCC_F_CALLED) |
| 327 | sign.called() = dec_number(&in_mncc->called); |
| 328 | if (in_mncc->fields & MNCC_F_CALLING) |
| 329 | sign.calling() = dec_number(&in_mncc->calling); |
| 330 | if (in_mncc->fields & MNCC_F_REDIRECTING) |
| 331 | sign.redirecting() = dec_number(&in_mncc->redirecting); |
| 332 | if (in_mncc->fields & MNCC_F_CONNECTED) |
| 333 | sign.connected() = dec_number(&in_mncc->connected); |
| 334 | if (in_mncc->fields & MNCC_F_CAUSE) { |
| 335 | sign.cause() = MNCC__cause(in_mncc->cause.location, |
| 336 | in_mncc->cause.coding, |
| 337 | in_mncc->cause.rec, |
| 338 | in_mncc->cause.rec_val, |
| 339 | in_mncc->cause.value, |
| 340 | OCTETSTRING(in_mncc->cause.diag_len, |
| 341 | (const uint8_t *)in_mncc->cause.diag)); |
| 342 | } |
| 343 | if (in_mncc->fields & MNCC_F_USERUSER) { |
| 344 | sign.useruser() = MNCC__useruser(in_mncc->useruser.proto, |
| 345 | CHARSTRING(in_mncc->useruser.info)); |
| 346 | } |
| 347 | if (in_mncc->fields & MNCC_F_PROGRESS) { |
| 348 | sign.progress() = MNCC__progress(in_mncc->progress.coding, |
| 349 | in_mncc->progress.location, |
| 350 | in_mncc->progress.descr); |
| 351 | } |
| 352 | if (in_mncc->fields & MNCC_F_EMERGENCY) |
| 353 | sign.emergency() = in_mncc->emergency; |
| 354 | if (in_mncc->fields & MNCC_F_FACILITY) |
| 355 | sign.facility() = CHARSTRING(in_mncc->facility.info); |
| 356 | if (in_mncc->fields & MNCC_F_SSVERSION) |
| 357 | sign.ssversion() = CHARSTRING(in_mncc->ssversion.info); |
| 358 | if (in_mncc->fields & MNCC_F_CCCAP) |
| 359 | sign.cccap() = MNCC__cccap(in_mncc->cccap.dtmf, in_mncc->cccap.pcp); |
Harald Welte | d13700d | 2018-02-02 20:06:52 +0100 | [diff] [blame] | 360 | if (in_mncc->fields & MNCC_F_KEYPAD) { |
| 361 | char kpd[2] = { (char) in_mncc->keypad, 0 }; |
| 362 | sign.keypad() = CHARSTRING(kpd); |
| 363 | } |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 364 | if (in_mncc->fields & MNCC_F_SIGNAL) |
| 365 | sign.signal() = in_mncc->signal; |
| 366 | |
| 367 | sign.clir__sup() = in_mncc->clir.sup; |
| 368 | sign.clir__inv() = in_mncc->clir.inv; |
| 369 | sign.more() = in_mncc->more; |
| 370 | sign.notify() = in_mncc->notify; |
| 371 | sign.imsi() = CHARSTRING(in_mncc->imsi); |
| 372 | sign.lchan__type() = in_mncc->lchan_type; |
| 373 | sign.lchan__mode() = in_mncc->lchan_mode; |
Vadim Yanitskiy | 9ff4780 | 2021-10-28 14:55:58 +0300 | [diff] [blame] | 374 | if (mncc_sock_version > 7) { |
| 375 | if (in_mncc->fields & MNCC_F_GCR) |
| 376 | sign.gcr() = OCTETSTRING(sizeof(in_mncc->v8.gcr), in_mncc->v8.gcr); |
| 377 | sign.sdp() = in_mncc->v8.sdp; |
| 378 | } else { |
| 379 | sign.sdp() = in_mncc->v7.sdp; |
| 380 | } |
Harald Welte | 474fd7d | 2017-12-29 16:01:39 +0100 | [diff] [blame] | 381 | u.signal() = sign; |
| 382 | break; |
| 383 | } |
| 384 | return MNCC__PDU(in_mncc->msg_type, u); |
| 385 | } |
| 386 | |
| 387 | } |