anjana_sreekumar@infosys.com | 991c206 | 2020-01-08 11:42:57 +0530 | [diff] [blame^] | 1 | /* |
| 2 | * |
| 3 | * Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd. |
| 4 | * Copyright (c) 2017 Intel Corporation |
| 5 | * Copyright (c) 2019-Present, Infosys Ltd. |
| 6 | * |
| 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | * you may not use this file except in compliance with the License. |
| 9 | * You may obtain a copy of the License at |
| 10 | * |
| 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | * |
| 13 | * Unless required by applicable law or agreed to in writing, software |
| 14 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | * See the License for the specific language governing permissions and |
| 17 | * limitations under the License. |
| 18 | */ |
| 19 | |
| 20 | |
| 21 | #include <stdio.h> |
| 22 | #include <stdlib.h> |
| 23 | #include <unistd.h> |
| 24 | #include <string.h> |
| 25 | #include <pthread.h> |
| 26 | |
| 27 | #include "options.h" |
| 28 | #include "ipc_api.h" |
| 29 | #include "main.h" |
| 30 | #include "s1ap.h" |
| 31 | #include "s1ap_config.h" |
| 32 | #include "sctp_conn.h" |
| 33 | #include "s1ap_structs.h" |
| 34 | #include "s1ap_msg_codes.h" |
| 35 | #include "s1ap_ie.h" |
| 36 | #include "ProtocolIE-ID.h" |
| 37 | #include "ProtocolIE-Field.h" |
| 38 | #include "common_proc_info.h" |
| 39 | #include "InitiatingMessage.h" |
| 40 | #include "UE-S1AP-ID-pair.h" |
| 41 | #include "msgType.h" |
| 42 | |
| 43 | extern s1ap_config g_s1ap_cfg; |
| 44 | |
| 45 | int s1ap_mme_encode_initiating( |
| 46 | struct s1ap_common_req_Q_msg *message_p, |
| 47 | uint8_t **buffer, |
| 48 | uint32_t *length) |
| 49 | { |
| 50 | log_msg(LOG_INFO, "MME initiating msg Encode.\n"); |
| 51 | switch (message_p->IE_type) { |
| 52 | case S1AP_CTX_REL_CMD: |
| 53 | log_msg(LOG_INFO, "Ue Context release Command Encode.\n"); |
| 54 | return s1ap_mme_encode_ue_context_release_command( |
| 55 | message_p, buffer, length); |
| 56 | case S1AP_PAGING_REQ: |
| 57 | log_msg(LOG_INFO, "Paging req Encode.\n"); |
| 58 | return s1ap_mme_encode_paging_request( |
| 59 | message_p, buffer, length); |
| 60 | case S1AP_INIT_CTXT_SETUP_REQ: |
| 61 | log_msg(LOG_INFO, "Init context setup req encode\n"); |
| 62 | return s1ap_mme_encode_initial_context_setup_request( |
| 63 | message_p, buffer, length); |
| 64 | default: |
| 65 | log_msg( |
| 66 | LOG_WARNING, |
| 67 | "Unknown procedure ID (%d) for initiating message_p\n", |
| 68 | (int) message_p->IE_type); |
| 69 | } |
| 70 | |
| 71 | return -1; |
| 72 | } |
| 73 | |
| 74 | int s1ap_mme_encode_ue_context_release_command( |
| 75 | struct s1ap_common_req_Q_msg *s1apPDU, |
| 76 | uint8_t **buffer, |
| 77 | uint32_t *length) |
| 78 | { |
| 79 | log_msg(LOG_DEBUG,"Inside s1ap_encoder\n"); |
| 80 | |
| 81 | S1AP_PDU_t pdu = {(S1AP_PDU_PR_NOTHING)}; |
| 82 | InitiatingMessage_t *initiating_msg = NULL; |
| 83 | S1AP_PDU_t *pdu_p = &pdu; |
| 84 | int enc_ret = -1; |
| 85 | memset ((void *)pdu_p, 0, sizeof (S1AP_PDU_t)); |
| 86 | |
| 87 | pdu.present = S1AP_PDU_PR_initiatingMessage; |
| 88 | pdu.choice.initiatingMessage = calloc(sizeof(InitiatingMessage_t), sizeof(uint8_t)); |
| 89 | if(pdu.choice.initiatingMessage == NULL) |
| 90 | { |
| 91 | log_msg(LOG_ERROR,"calloc failed.\n"); |
| 92 | return -1; |
| 93 | } |
| 94 | initiating_msg = pdu.choice.initiatingMessage; |
| 95 | initiating_msg->procedureCode = ProcedureCode_id_UEContextRelease; |
| 96 | initiating_msg->criticality = 0; |
| 97 | initiating_msg->value.present = InitiatingMessage__value_PR_UEContextReleaseCommand; |
| 98 | |
| 99 | UEContextReleaseCommand_IEs_t val[2]; |
| 100 | memset(val, 0, 2 * sizeof(UEContextReleaseCommand_IEs_t)); |
| 101 | |
| 102 | UE_S1AP_IDs_t ue_id_val; |
| 103 | memset(&ue_id_val, 0, sizeof(UE_S1AP_IDs_t)); |
| 104 | |
| 105 | struct UE_S1AP_ID_pair s1apId_pair; |
| 106 | if((s1apPDU->mme_s1ap_ue_id != 0xFFFFFFFF) |
| 107 | && (s1apPDU->enb_s1ap_ue_id != 0xFFFFFFFF)) |
| 108 | { |
| 109 | log_msg(LOG_INFO,"S1ap Id pair.\n"); |
| 110 | ue_id_val.present = UE_S1AP_IDs_PR_uE_S1AP_ID_pair; |
| 111 | s1apId_pair.eNB_UE_S1AP_ID = s1apPDU->enb_s1ap_ue_id; |
| 112 | s1apId_pair.mME_UE_S1AP_ID = s1apPDU->mme_s1ap_ue_id; |
| 113 | ue_id_val.choice.uE_S1AP_ID_pair = calloc(sizeof(struct UE_S1AP_ID_pair), sizeof(uint8_t)); |
| 114 | if(ue_id_val.choice.uE_S1AP_ID_pair == NULL) |
| 115 | { |
| 116 | log_msg(LOG_ERROR,"calloc failed.\n"); |
| 117 | free(pdu.choice.initiatingMessage); |
| 118 | return -1; |
| 119 | } |
| 120 | memcpy(ue_id_val.choice.uE_S1AP_ID_pair, &s1apId_pair, sizeof(struct UE_S1AP_ID_pair)); |
| 121 | } |
| 122 | else if(s1apPDU->mme_s1ap_ue_id != 0xFFFFFFFF) |
| 123 | { |
| 124 | ue_id_val.present = UE_S1AP_IDs_PR_mME_UE_S1AP_ID; |
| 125 | ue_id_val.choice.mME_UE_S1AP_ID = s1apPDU->mme_s1ap_ue_id; |
| 126 | } |
| 127 | else |
| 128 | { |
| 129 | ue_id_val.present = UE_S1AP_IDs_PR_NOTHING; |
| 130 | } |
| 131 | |
| 132 | val[0].id = ProtocolIE_ID_id_UE_S1AP_IDs; |
| 133 | val[0].criticality = 0; |
| 134 | val[0].value.present = UEContextReleaseCommand_IEs__value_PR_UE_S1AP_IDs; |
| 135 | memcpy(&val[0].value.choice.UE_S1AP_IDs, &ue_id_val, sizeof(UE_S1AP_IDs_t)); |
| 136 | |
| 137 | val[1].id = ProtocolIE_ID_id_Cause; |
| 138 | val[1].criticality = 1; |
| 139 | val[1].value.present = UEContextReleaseCommand_IEs__value_PR_Cause; |
| 140 | //memcpy(&val[1].value.choice.Cause, &s1apPDU->cause, sizeof(Cause_t)); |
| 141 | val[1].value.choice.Cause.present = s1apPDU->cause.present; |
| 142 | switch(s1apPDU->cause.present) |
| 143 | { |
| 144 | case Cause_PR_radioNetwork: |
| 145 | val[1].value.choice.Cause.choice.radioNetwork |
| 146 | = s1apPDU->cause.choice.radioNetwork; |
| 147 | break; |
| 148 | case Cause_PR_transport: |
| 149 | val[1].value.choice.Cause.choice.transport |
| 150 | = s1apPDU->cause.choice.transport; |
| 151 | break; |
| 152 | case Cause_PR_nas: |
| 153 | val[1].value.choice.Cause.choice.nas |
| 154 | = s1apPDU->cause.choice.nas; |
| 155 | break; |
| 156 | case Cause_PR_protocol: |
| 157 | val[1].value.choice.Cause.choice.protocol |
| 158 | = s1apPDU->cause.choice.protocol; |
| 159 | break; |
| 160 | case Cause_PR_misc: |
| 161 | val[1].value.choice.Cause.choice.misc |
| 162 | = s1apPDU->cause.choice.misc; |
| 163 | break; |
| 164 | case Cause_PR_NOTHING: |
| 165 | default: |
| 166 | log_msg(LOG_WARNING,"Unknown Cause type:%d\n",s1apPDU->cause.present); |
| 167 | } |
| 168 | |
| 169 | log_msg(LOG_INFO,"Add values to list.\n"); |
| 170 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.UEContextReleaseCommand.protocolIEs.list, &val[0]); |
| 171 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.UEContextReleaseCommand.protocolIEs.list, &val[1]); |
| 172 | |
| 173 | if ((enc_ret = aper_encode_to_new_buffer (&asn_DEF_S1AP_PDU, 0, &pdu, (void **)buffer)) < 0) |
| 174 | { |
| 175 | log_msg(LOG_ERROR, "Encoding of Ctx Release Cmd failed\n"); |
| 176 | return -1; |
| 177 | } |
| 178 | |
| 179 | log_msg(LOG_INFO,"free allocated msgs"); |
| 180 | free(ue_id_val.choice.uE_S1AP_ID_pair); |
| 181 | free(pdu.choice.initiatingMessage); |
| 182 | |
| 183 | *length = enc_ret; |
| 184 | return enc_ret; |
| 185 | } |
| 186 | |
| 187 | int s1ap_mme_encode_initial_context_setup_request( |
| 188 | struct s1ap_common_req_Q_msg *s1apPDU, |
| 189 | uint8_t **buffer, |
| 190 | uint32_t *length) |
| 191 | { |
| 192 | S1AP_PDU_t pdu = {(S1AP_PDU_PR_NOTHING)}; |
| 193 | InitiatingMessage_t *initiating_msg = NULL; |
| 194 | S1AP_PDU_t *pdu_p = &pdu; |
| 195 | int enc_ret = -1; |
| 196 | memset ((void *)pdu_p, 0, sizeof (S1AP_PDU_t)); |
| 197 | |
| 198 | pdu.present = S1AP_PDU_PR_initiatingMessage; |
| 199 | pdu.choice.initiatingMessage = calloc (sizeof(InitiatingMessage_t), sizeof(uint8_t)); |
| 200 | if(pdu.choice.initiatingMessage == NULL) |
| 201 | { |
| 202 | log_msg(LOG_ERROR,"calloc failed.\n"); |
| 203 | return -1; |
| 204 | } |
| 205 | initiating_msg = pdu.choice.initiatingMessage; |
| 206 | initiating_msg->procedureCode = ProcedureCode_id_InitialContextSetup; |
| 207 | initiating_msg->criticality = 0; |
| 208 | initiating_msg->value.present = InitiatingMessage__value_PR_InitialContextSetupRequest; |
| 209 | |
| 210 | InitialContextSetupRequestIEs_t val[6]; |
| 211 | memset(val, 0, 6 * (sizeof(InitialContextSetupRequestIEs_t))); |
| 212 | |
| 213 | val[0].id = ProtocolIE_ID_id_MME_UE_S1AP_ID; |
| 214 | val[0].criticality = 0; |
| 215 | val[0].value.present = InitialContextSetupRequestIEs__value_PR_MME_UE_S1AP_ID; |
| 216 | val[0].value.choice.MME_UE_S1AP_ID = s1apPDU->mme_s1ap_ue_id; |
| 217 | |
| 218 | val[1].id = ProtocolIE_ID_id_eNB_UE_S1AP_ID; |
| 219 | val[1].criticality = 0; |
| 220 | val[1].value.present = InitialContextSetupRequestIEs__value_PR_ENB_UE_S1AP_ID; |
| 221 | val[1].value.choice.ENB_UE_S1AP_ID = s1apPDU->enb_s1ap_ue_id; |
| 222 | |
| 223 | val[2].id = ProtocolIE_ID_id_uEaggregateMaximumBitrate; |
| 224 | val[2].criticality = 0; |
| 225 | val[2].value.present = InitialContextSetupRequestIEs__value_PR_UEAggregateMaximumBitrate; |
| 226 | |
| 227 | val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL.size = 5; |
| 228 | val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL.buf = calloc (5, sizeof(uint8_t)); |
| 229 | val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL.buf[0] = 0x0; |
| 230 | uint32_t temp_bitrate = htonl(s1apPDU->ueag_max_dl_bitrate); |
| 231 | memcpy (&(val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL.buf[1]), &temp_bitrate, sizeof(uint32_t)); |
| 232 | |
| 233 | val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL.size = 5; |
| 234 | val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL.buf = calloc (5, sizeof(uint8_t)); |
| 235 | val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL.buf[0] = 0x0; |
| 236 | temp_bitrate = htonl(s1apPDU->ueag_max_ul_bitrate); |
| 237 | memcpy (&(val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL.buf[1]), &temp_bitrate, sizeof(uint32_t)); |
| 238 | |
| 239 | val[3].id = ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq; |
| 240 | val[3].criticality = 0; |
| 241 | val[3].value.present = InitialContextSetupRequestIEs__value_PR_E_RABToBeSetupListCtxtSUReq; |
| 242 | |
| 243 | E_RABToBeSetupItemCtxtSUReqIEs_t erab_to_be_setup_item; |
| 244 | memset(&erab_to_be_setup_item, 0, sizeof(E_RABToBeSetupItemCtxtSUReqIEs_t)); |
| 245 | E_RABToBeSetupItemCtxtSUReq_t* erab_to_be_setup = &(erab_to_be_setup_item.value.choice.E_RABToBeSetupItemCtxtSUReq); |
| 246 | |
| 247 | erab_to_be_setup_item.id = ProtocolIE_ID_id_E_RABToBeSetupItemCtxtSUReq; |
| 248 | erab_to_be_setup_item.criticality = 0; |
| 249 | erab_to_be_setup_item.value.present = E_RABToBeSetupItemCtxtSUReqIEs__value_PR_E_RABToBeSetupItemCtxtSUReq; |
| 250 | |
| 251 | erab_to_be_setup->e_RAB_ID = 5; |
| 252 | |
| 253 | erab_to_be_setup->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel = 15; |
| 254 | erab_to_be_setup->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability = 1; |
| 255 | erab_to_be_setup->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability = 1; |
| 256 | erab_to_be_setup->e_RABlevelQoSParameters.qCI = 9; |
| 257 | |
| 258 | erab_to_be_setup->transportLayerAddress.size = 4; |
| 259 | erab_to_be_setup->transportLayerAddress.buf = calloc(4, sizeof(uint8_t)); |
| 260 | uint32_t transport_layer_address = htonl(s1apPDU->gtp_teid.ip.ipv4.s_addr); |
| 261 | memcpy(erab_to_be_setup->transportLayerAddress.buf, &transport_layer_address, sizeof(uint32_t)); |
| 262 | |
| 263 | |
| 264 | erab_to_be_setup->gTP_TEID.size = 4; |
| 265 | erab_to_be_setup->gTP_TEID.buf = calloc(4, sizeof(uint8_t)); |
| 266 | erab_to_be_setup->gTP_TEID.buf[0] = s1apPDU->gtp_teid.header.teid_gre >> 24; |
| 267 | erab_to_be_setup->gTP_TEID.buf[1] = s1apPDU->gtp_teid.header.teid_gre >> 16; |
| 268 | erab_to_be_setup->gTP_TEID.buf[2] = s1apPDU->gtp_teid.header.teid_gre >> 8; |
| 269 | erab_to_be_setup->gTP_TEID.buf[3] = s1apPDU->gtp_teid.header.teid_gre; |
| 270 | |
| 271 | ASN_SEQUENCE_ADD(&(val[3].value.choice.E_RABToBeSetupListCtxtSUReq.list), &erab_to_be_setup_item); |
| 272 | |
| 273 | val[4].id = ProtocolIE_ID_id_UESecurityCapabilities; |
| 274 | val[4].criticality = 0; |
| 275 | val[4].value.present = InitialContextSetupRequestIEs__value_PR_UESecurityCapabilities; |
| 276 | val[4].value.choice.UESecurityCapabilities.encryptionAlgorithms.buf = calloc(2, sizeof(uint8_t)); |
| 277 | val[4].value.choice.UESecurityCapabilities.encryptionAlgorithms.size = 2; |
| 278 | val[4].value.choice.UESecurityCapabilities.encryptionAlgorithms.buf[0] = 0xe0; |
| 279 | val[4].value.choice.UESecurityCapabilities.encryptionAlgorithms.buf[1] = 0x00; |
| 280 | val[4].value.choice.UESecurityCapabilities.integrityProtectionAlgorithms.buf = calloc(2, sizeof(uint8_t)); |
| 281 | val[4].value.choice.UESecurityCapabilities.integrityProtectionAlgorithms.size = 2; |
| 282 | val[4].value.choice.UESecurityCapabilities.integrityProtectionAlgorithms.buf[0] = 0xc0; |
| 283 | val[4].value.choice.UESecurityCapabilities.integrityProtectionAlgorithms.buf[1] = 0x00; |
| 284 | |
| 285 | val[5].id = ProtocolIE_ID_id_SecurityKey; |
| 286 | val[5].criticality = 0; |
| 287 | val[5].value.present = InitialContextSetupRequestIEs__value_PR_SecurityKey; |
| 288 | val[5].value.choice.SecurityKey.size = SECURITY_KEY_SIZE; |
| 289 | val[5].value.choice.SecurityKey.buf = calloc(SECURITY_KEY_SIZE, sizeof(uint8_t)); |
| 290 | memcpy(val[5].value.choice.SecurityKey.buf, s1apPDU->sec_key, SECURITY_KEY_SIZE); |
| 291 | |
| 292 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.InitialContextSetupRequest.protocolIEs.list, &val[0]); |
| 293 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.InitialContextSetupRequest.protocolIEs.list, &val[1]); |
| 294 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.InitialContextSetupRequest.protocolIEs.list, &val[2]); |
| 295 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.InitialContextSetupRequest.protocolIEs.list, &val[3]); |
| 296 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.InitialContextSetupRequest.protocolIEs.list, &val[4]); |
| 297 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.InitialContextSetupRequest.protocolIEs.list, &val[5]); |
| 298 | |
| 299 | if ((enc_ret = aper_encode_to_new_buffer (&asn_DEF_S1AP_PDU, 0, &pdu, (void **)buffer)) < 0) |
| 300 | { |
| 301 | log_msg(LOG_ERROR, "Encoding of Initial Context Setup Request failed\n"); |
| 302 | return -1; |
| 303 | } |
| 304 | |
| 305 | log_msg(LOG_INFO,"free allocated messages\n"); |
| 306 | |
| 307 | free(val[5].value.choice.SecurityKey.buf); |
| 308 | free(val[4].value.choice.UESecurityCapabilities.integrityProtectionAlgorithms.buf); |
| 309 | free(val[4].value.choice.UESecurityCapabilities.encryptionAlgorithms.buf); |
| 310 | free(erab_to_be_setup->gTP_TEID.buf); |
| 311 | free(erab_to_be_setup->transportLayerAddress.buf); |
| 312 | free(val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL.buf); |
| 313 | free(val[2].value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL.buf); |
| 314 | free(pdu.choice.initiatingMessage); |
| 315 | |
| 316 | *length = enc_ret; |
| 317 | return enc_ret; |
| 318 | } |
| 319 | |
| 320 | int s1ap_mme_encode_paging_request( |
| 321 | struct s1ap_common_req_Q_msg *s1apPDU, |
| 322 | uint8_t **buffer, |
| 323 | uint32_t *length) |
| 324 | { |
| 325 | |
| 326 | |
| 327 | S1AP_PDU_t pdu = {(S1AP_PDU_PR_NOTHING)}; |
| 328 | InitiatingMessage_t *initiating_msg = NULL; |
| 329 | S1AP_PDU_t *pdu_p = &pdu; |
| 330 | int enc_ret = -1; |
| 331 | memset ((void *)pdu_p, 0, sizeof (S1AP_PDU_t)); |
| 332 | |
| 333 | pdu.present = S1AP_PDU_PR_initiatingMessage; |
| 334 | pdu.choice.initiatingMessage = calloc (sizeof(InitiatingMessage_t), sizeof(uint8_t)); |
| 335 | if(pdu.choice.initiatingMessage == NULL) |
| 336 | { |
| 337 | log_msg(LOG_ERROR,"calloc failed.\n"); |
| 338 | return -1; |
| 339 | } |
| 340 | |
| 341 | initiating_msg = pdu.choice.initiatingMessage; |
| 342 | initiating_msg->procedureCode = ProcedureCode_id_Paging; |
| 343 | initiating_msg->criticality = 0; |
| 344 | initiating_msg->value.present = InitiatingMessage__value_PR_Paging; |
| 345 | |
| 346 | PagingIEs_t val[4]; |
| 347 | memset(val, 0, 4 * sizeof(PagingIEs_t)); |
| 348 | |
| 349 | val[0].id = ProtocolIE_ID_id_UEIdentityIndexValue; |
| 350 | val[0].criticality = 0; |
| 351 | val[0].value.present = PagingIEs__value_PR_UEIdentityIndexValue; |
| 352 | |
| 353 | UEIdentityIndexValue_t* UEIdentityIndexValue = &val[0].value.choice.UEIdentityIndexValue; |
| 354 | uint64_t ue_imsi_value = 0; |
| 355 | /* Set UE Identity Index value : IMSI mod 4096 */ |
| 356 | UEIdentityIndexValue->size = 2; |
| 357 | UEIdentityIndexValue->buf = calloc(2, sizeof(uint8_t)); |
| 358 | |
| 359 | /* Conver string to value */ |
| 360 | uint8_t imsi_bcd[BCD_IMSI_STR_LEN]; |
| 361 | convert_imsi_to_bcd_str(s1apPDU->imsi, imsi_bcd); |
| 362 | for (int i = 0; i < BCD_IMSI_STR_LEN; i++) |
| 363 | { |
| 364 | ue_imsi_value = ue_imsi_value*10 + (imsi_bcd[i] - '0'); |
| 365 | } |
| 366 | |
| 367 | /* index(10bit) = ue_imsi_value mod 1024 */ |
| 368 | uint16_t index_value = ue_imsi_value % 1024; |
| 369 | UEIdentityIndexValue->buf[0] = index_value >> 2; |
| 370 | UEIdentityIndexValue->buf[1] = (index_value & 0x3f) << 6; |
| 371 | UEIdentityIndexValue->bits_unused = 6; |
| 372 | |
| 373 | log_msg(LOG_DEBUG,"Encoding STMSI\n"); |
| 374 | |
| 375 | val[1].id = ProtocolIE_ID_id_UEPagingID; |
| 376 | val[1].criticality = 0; |
| 377 | val[1].value.present = PagingIEs__value_PR_UEPagingID; |
| 378 | |
| 379 | UEPagingID_t pagingId; |
| 380 | pagingId.present = UEPagingID_PR_s_TMSI; |
| 381 | pagingId.choice.s_TMSI = calloc(sizeof(struct S_TMSI), sizeof(uint8_t)); |
| 382 | if(pagingId.choice.s_TMSI == NULL) |
| 383 | { |
| 384 | log_msg(LOG_ERROR,"malloc failed.\n"); |
| 385 | free(pdu.choice.initiatingMessage); |
| 386 | return -1; |
| 387 | } |
| 388 | |
| 389 | pagingId.choice.s_TMSI->mMEC.buf = calloc(1, sizeof(uint8_t)); |
| 390 | if(NULL == pagingId.choice.s_TMSI->mMEC.buf) |
| 391 | { |
| 392 | log_msg(LOG_ERROR,"malloc failed.\n"); |
| 393 | free(pdu.choice.initiatingMessage); |
| 394 | free(pagingId.choice.s_TMSI); |
| 395 | return -1; |
| 396 | } |
| 397 | |
| 398 | memcpy(pagingId.choice.s_TMSI->mMEC.buf, &g_s1ap_cfg.mme_code, sizeof(uint8_t)); |
| 399 | pagingId.choice.s_TMSI->mMEC.size = sizeof(uint8_t); |
| 400 | |
| 401 | pagingId.choice.s_TMSI->m_TMSI.buf = calloc(sizeof(uint32_t), sizeof(uint8_t)); |
| 402 | if(NULL == pagingId.choice.s_TMSI->m_TMSI.buf) |
| 403 | { |
| 404 | log_msg(LOG_ERROR,"malloc failed.\n"); |
| 405 | free(pdu.choice.initiatingMessage); |
| 406 | free(pagingId.choice.s_TMSI); |
| 407 | free(pagingId.choice.s_TMSI->mMEC.buf); |
| 408 | return -1; |
| 409 | } |
| 410 | |
| 411 | uint32_t ue_idx = htonl(s1apPDU->ue_idx); |
| 412 | memcpy(pagingId.choice.s_TMSI->m_TMSI.buf, &ue_idx, sizeof(uint32_t)); |
| 413 | pagingId.choice.s_TMSI->m_TMSI.size = sizeof(uint32_t); |
| 414 | memcpy(&val[1].value.choice.UEPagingID, &pagingId, sizeof(UEPagingID_t)); |
| 415 | |
| 416 | log_msg(LOG_INFO, "Encoding CNDomain\n"); |
| 417 | |
| 418 | val[2].id = ProtocolIE_ID_id_CNDomain; |
| 419 | val[2].criticality = 0; |
| 420 | val[2].value.present = PagingIEs__value_PR_CNDomain; |
| 421 | val[2].value.choice.CNDomain = s1apPDU->cn_domain; |
| 422 | |
| 423 | log_msg(LOG_DEBUG,"Encoding TAI List\n"); |
| 424 | |
| 425 | val[3].id = ProtocolIE_ID_id_TAIList; |
| 426 | val[3].criticality = 0; |
| 427 | val[3].value.present = PagingIEs__value_PR_TAIList; |
| 428 | |
| 429 | TAIItemIEs_t tai_item; |
| 430 | memset(&tai_item, 0, sizeof(TAIItemIEs_t)); |
| 431 | |
| 432 | tai_item.id = ProtocolIE_ID_id_TAIItem; |
| 433 | tai_item.criticality = 0; |
| 434 | tai_item.value.present = TAIItemIEs__value_PR_TAIItem; |
| 435 | |
| 436 | log_msg(LOG_DEBUG,"TAI List - Encode PLMN ID\n"); |
| 437 | tai_item.value.choice.TAIItem.tAI.pLMNidentity.size = 3; |
| 438 | tai_item.value.choice.TAIItem.tAI.pLMNidentity.buf = calloc(3, sizeof(uint8_t)); |
| 439 | memcpy(tai_item.value.choice.TAIItem.tAI.pLMNidentity.buf, &s1apPDU->tai.plmn_id.idx, 3); |
| 440 | |
| 441 | log_msg(LOG_DEBUG,"TAI List - Encode TAC\n"); |
| 442 | tai_item.value.choice.TAIItem.tAI.tAC.size = 2; |
| 443 | tai_item.value.choice.TAIItem.tAI.tAC.buf = calloc(2, sizeof(uint8_t)); |
| 444 | memcpy(tai_item.value.choice.TAIItem.tAI.tAC.buf, &s1apPDU->tai.tac, 2); |
| 445 | |
| 446 | ASN_SEQUENCE_ADD(&val[3].value.choice.TAIList.list, &tai_item); |
| 447 | |
| 448 | log_msg(LOG_INFO,"Add values to list.\n"); |
| 449 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.Paging.protocolIEs.list, &val[0]); |
| 450 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.Paging.protocolIEs.list, &val[1]); |
| 451 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.Paging.protocolIEs.list, &val[2]); |
| 452 | ASN_SEQUENCE_ADD(&initiating_msg->value.choice.Paging.protocolIEs.list, &val[3]); |
| 453 | |
| 454 | if ((enc_ret = aper_encode_to_new_buffer (&asn_DEF_S1AP_PDU, 0, &pdu, (void **)buffer)) < 0) |
| 455 | { |
| 456 | log_msg(LOG_ERROR, "Encoding of Paging failed\n"); |
| 457 | return -1; |
| 458 | } |
| 459 | |
| 460 | log_msg(LOG_INFO,"free allocated msgs"); |
| 461 | free(pdu.choice.initiatingMessage); |
| 462 | free(UEIdentityIndexValue->buf); |
| 463 | free(pagingId.choice.s_TMSI->mMEC.buf); |
| 464 | free(pagingId.choice.s_TMSI->m_TMSI.buf); |
| 465 | free(pagingId.choice.s_TMSI); |
| 466 | free(tai_item.value.choice.TAIItem.tAI.pLMNidentity.buf); |
| 467 | free(tai_item.value.choice.TAIItem.tAI.tAC.buf); |
| 468 | |
| 469 | *length = enc_ret; |
| 470 | return enc_ret; |
| 471 | } |