blob: 39f16bb4dbe87d0d557374dbac6b5601ecf04b9e [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301/*
2 * Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd.
3 * Copyright (c) 2017 Intel Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <pthread.h>
21#include <string.h>
22#include <unistd.h>
23#include <stdint.h>
24
25#include "err_codes.h"
26#include "ipc_api.h"
27#include "main.h"
28#include "msgType.h"
29#include "s1ap.h"
30#include "log.h"
31#include "snow_3g.h"
32
33/****Globals and externs ***/
34
35/*Making global just to avoid stack passing*/
36static Buffer g_esm_buffer;
37static Buffer g_esm_value_buffer;
38static Buffer g_esm_nas_buffer;
39
40
41/****Global and externs end***/
42extern ipc_handle ipc_S1ap_Hndl;
43/**
44* Get ProtocolIE value for Sec Request sent by mme-app
45*/
46static int
47get_esmreq_protoie_value(struct proto_IE *value, struct esm_req_Q_msg * g_esmReqInfo)
48{
49 value->no_of_IEs = ESM_REQ_NO_OF_IES;
50
51 value->data = (proto_IEs *) malloc(ESM_REQ_NO_OF_IES *
52 sizeof(proto_IEs));
53
54 value->data[0].val.mme_ue_s1ap_id = g_esmReqInfo->ue_idx;
55 value->data[1].val.enb_ue_s1ap_id = g_esmReqInfo->enb_s1ap_ue_id;
56
57 value->data[2].val.nas.header.security_header_type =
58 IntegrityProtectedCiphered;
59
60 value->data[2].val.nas.header.proto_discriminator =
61 EPSMobilityManagementMessages;
62
63 /* placeholder for mac. mac value will be calculated later */
64 uint8_t mac[MAC_SIZE] = {0};
65 memcpy(value->data[2].val.nas.header.mac, mac, MAC_SIZE);
66
67 value->data[2].val.nas.header.seq_no = g_esmReqInfo->dl_seq_no;
68
69 value->data[2].val.nas.header.message_type = ESMInformationRequest;
70
71 /* TODO: Remove hardcoded value */
72 value->data[2].val.nas.header.eps_bearer_identity = 0;
73 value->data[2].val.nas.header.procedure_trans_identity = g_esmReqInfo->pti;
74
75 return SUCCESS;
76}
77
78
79/**
80* Stage specific message processing.
81*/
82static int
83esmreq_processing(struct esm_req_Q_msg * g_esmReqInfo)
84{
85 unsigned char tmpStr[4];
86 struct s1ap_PDU s1apPDU= {0};
87 uint8_t mac_data_pos;
88
89 s1apPDU.procedurecode = id_downlinkNASTransport;
90 s1apPDU.criticality = CRITICALITY_IGNORE;
91
92 get_esmreq_protoie_value(&s1apPDU.value, g_esmReqInfo);
93
94 /* Copy values to g_sec_nas_buffer */
95
96 /* id-NAS-PDU */
97 g_esm_nas_buffer.pos = 0;
98 nasPDU nas = s1apPDU.value.data[2].val.nas;
99
100 unsigned char value = (nas.header.security_header_type << 4 |
101 nas.header.proto_discriminator);
102 buffer_copy(&g_esm_nas_buffer, &value, sizeof(value));
103
104 /* placeholder for mac. mac value will be calculated later */
105 buffer_copy(&g_esm_nas_buffer, &nas.header.mac, MAC_SIZE);
106 mac_data_pos = g_esm_nas_buffer.pos;
107
108 buffer_copy(&g_esm_nas_buffer, &nas.header.seq_no,
109 sizeof(nas.header.seq_no));
110
111 nas.header.proto_discriminator = EPSSessionManagementMessage;
112 value = (nas.header.eps_bearer_identity << 4 |
113 nas.header.proto_discriminator);
114 buffer_copy(&g_esm_nas_buffer, &value, sizeof(value));
115
116 buffer_copy(&g_esm_nas_buffer,
117 &nas.header.procedure_trans_identity,
118 sizeof(nas.header.procedure_trans_identity));
119
120 buffer_copy(&g_esm_nas_buffer, &nas.header.message_type,
121 sizeof(nas.header.message_type));
122
123 /* Calculate mac */
124 uint8_t direction = 1;
125 uint8_t bearer = 0;
126
127 calculate_mac(g_esmReqInfo->int_key, nas.header.seq_no, direction,
128 bearer, &g_esm_nas_buffer.buf[mac_data_pos],
129 g_esm_nas_buffer.pos - mac_data_pos,
130 &g_esm_nas_buffer.buf[mac_data_pos - MAC_SIZE]);
131
132 /* Copy values in g_sec_value_buffer */
133 g_esm_value_buffer.pos = 0;
134
135 /* TODO remove hardcoded values */
136 char chProtoIENo[3] = {0,0,3};
137 buffer_copy(&g_esm_value_buffer, chProtoIENo, 3);
138
139 /* id-MME-UE-S1AP-ID */
140 uint16_t protocolIe_Id = id_MME_UE_S1AP_ID;
141 copyU16(tmpStr, protocolIe_Id);
142 buffer_copy(&g_esm_value_buffer, tmpStr,
143 sizeof(protocolIe_Id));
144
145 unsigned char protocolIe_criticality = CRITICALITY_REJECT;
146 buffer_copy(&g_esm_value_buffer, &protocolIe_criticality,
147 sizeof(protocolIe_criticality));
148
149 unsigned char datalen = 2;
150
151 /* TODO need to add proper handling*/
152 unsigned char mme_ue_id[3];
153 datalen = copyU16(mme_ue_id, s1apPDU.value.data[0].val.mme_ue_s1ap_id);
154 buffer_copy(&g_esm_value_buffer, &datalen, sizeof(datalen));
155 buffer_copy(&g_esm_value_buffer, mme_ue_id, datalen);
156
157 /* id-eNB-UE-S1AP-ID */
158 protocolIe_Id = id_eNB_UE_S1AP_ID;
159 copyU16(tmpStr, protocolIe_Id);
160 buffer_copy(&g_esm_value_buffer, tmpStr,
161 sizeof(protocolIe_Id));
162
163 buffer_copy(&g_esm_value_buffer, &protocolIe_criticality,
164 sizeof(protocolIe_criticality));
165
166 /* TODO needs proper handling*/
167 unsigned char enb_ue_id[3];
168 datalen = copyU16(enb_ue_id, s1apPDU.value.data[1].val.enb_ue_s1ap_id);
169 buffer_copy(&g_esm_value_buffer, &datalen, sizeof(datalen));
170 buffer_copy(&g_esm_value_buffer, enb_ue_id, datalen);
171
172
173 /* id-NAS-PDU */
174 protocolIe_Id = id_NAS_PDU;
175 copyU16(tmpStr, protocolIe_Id);
176 buffer_copy(&g_esm_value_buffer, tmpStr,
177 sizeof(protocolIe_Id));
178
179 buffer_copy(&g_esm_value_buffer, &protocolIe_criticality,
180 sizeof(protocolIe_criticality));
181
182
183 datalen = g_esm_nas_buffer.pos + 1;
184 buffer_copy(&g_esm_value_buffer, &datalen,
185 sizeof(datalen));
186
187 buffer_copy(&g_esm_value_buffer, &g_esm_nas_buffer.pos,
188 sizeof(g_esm_nas_buffer.pos));
189
190 buffer_copy(&g_esm_value_buffer, &g_esm_nas_buffer,
191 g_esm_nas_buffer.pos);
192
193 /* Copy values in g_sec_buffer */
194 g_esm_buffer.pos = 0;
195
196 unsigned char initiating_message = 0; /* TODO: Add enum */
197 buffer_copy(&g_esm_buffer, &initiating_message,
198 sizeof(initiating_message));
199
200 buffer_copy(&g_esm_buffer, &s1apPDU.procedurecode,
201 sizeof(s1apPDU.procedurecode));
202
203 buffer_copy(&g_esm_buffer, &s1apPDU.criticality,
204 sizeof(s1apPDU.criticality));
205
206 buffer_copy(&g_esm_buffer, &g_esm_value_buffer.pos,
207 sizeof(g_esm_value_buffer.pos));
208
209 buffer_copy(&g_esm_buffer, &g_esm_value_buffer,
210 g_esm_value_buffer.pos);
211
212 send_sctp_msg(g_esmReqInfo->enb_fd, g_esm_buffer.buf, g_esm_buffer.pos, 1);
213
214 free(s1apPDU.value.data);
215
216 return SUCCESS;
217}
218
219void*
220esmreq_handler(void *data)
221{
222 log_msg(LOG_INFO, "ESM Info Request handler\n");
223 esmreq_processing((struct esm_req_Q_msg *)data);
224
225 return NULL;
226}