blob: 23c00a56b1b9d74a7759e75184c73023f168d891 [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 * Copyright (c) 2019, Infosys Ltd.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <pthread.h>
22#include <string.h>
23#include <unistd.h>
24#include <stdint.h>
25
26#include "log.h"
27#include "err_codes.h"
28#include "message_queues.h"
29#include "ipc_api.h"
30#include "s1ap_config.h"
31#include "main.h"
32#include "s1ap.h"
33#include "msgType.h"
34
35extern s1ap_config g_s1ap_cfg;
36
37static void
38get_negotiated_qos_value(struct esm_qos *qos)
39{
40 qos->delay_class = 1;
41 qos->reliability_class = 3;
42 qos->peak_throughput = 5;
43 qos->precedence_class = 2;
44 qos->mean_throughput = 31;
45 qos->traffic_class = 3;
46 qos->delivery_order = 2;
47 qos->delivery_err_sdu = 3;
48 qos->max_sdu_size = 140;
49 qos->mbr_ul = 254;
50 qos->mbr_dl = 86;
51 qos->residual_ber = 7;
52 qos->sdu_err_ratio = 6;
53 qos->transfer_delay = 18;
54 qos->trffic_prio = 3;
55 qos->gbr_ul = 86;
56 qos->gbr_dl = 86;
57 qos->sig_ind = 0;
58 qos->src_stat_desc = 0;
59 qos->mbr_dl_ext = 108;
60 qos->gbr_dl_ext = 0;
61 qos->mbr_ul_ext = 108;
62 qos->gbr_ul_ext = 0;
63
64 return;
65}
66
67/**
68* Get ProtocolIE value for ICS Request sent by mme-app
69*/
70static int
71get_icsreq_protoie_value(struct proto_IE *value, struct init_ctx_req_Q_msg *g_icsReqInfo)
72{
73 uint8_t ieCnt = 0;
74 uint8_t nasIeCnt = 0;
75
76 value->no_of_IEs = ICS_REQ_NO_OF_IES;
77
78 value->data = (proto_IEs *) malloc(ICS_REQ_NO_OF_IES *
79 sizeof(proto_IEs));
80
81
82 value->data[ieCnt].val.mme_ue_s1ap_id = g_icsReqInfo->ue_idx;
83 ieCnt++;
84
85 value->data[ieCnt].val.enb_ue_s1ap_id = g_icsReqInfo->enb_s1ap_ue_id;
86 ieCnt++;
87
88 log_msg(LOG_INFO, "mme_ue_s1ap_id %d and enb_ue_s1ap_id %d\n",
89 g_icsReqInfo->ue_idx, g_icsReqInfo->enb_s1ap_ue_id);
90
91 value->data[ieCnt].val.ue_aggrt_max_bit_rate.uEaggregateMaxBitRateDL =
92 g_icsReqInfo->exg_max_dl_bitrate;
93 value->data[ieCnt].val.ue_aggrt_max_bit_rate.uEaggregateMaxBitRateUL =
94 g_icsReqInfo->exg_max_ul_bitrate;
95 ieCnt++;
96
97 /* E-RABToBeSetupItemCtxtSUReq start */
98 ERABSetup *e_rab = &(value->data[ieCnt].val.E_RABToBeSetupItemCtxtSUReq);
99 /* TODO: Remove hardcoded values. */
100 e_rab->e_RAB_ID = 1;
101 e_rab->e_RAB_QoS_Params.qci = 9;
102 e_rab->e_RAB_QoS_Params.arPrio.prioLevel = 15;
103 e_rab->e_RAB_QoS_Params.arPrio.preEmptionCapab = 1;
104 e_rab->e_RAB_QoS_Params.arPrio.preEmptionVulnebility = 1;
105
106 /*S1u information : transport layer addr and teid*/
107 e_rab->transportLayerAddress = htonl(g_icsReqInfo->gtp_teid.ip.ipv4.s_addr);
108 //e_rab->gtp_teid = htonl(g_icsReqInfo->gtp_teid.header.teid_gre);
109 {
110 char *dst = (char *)&(e_rab->gtp_teid);
111 char *src = (char *)&(g_icsReqInfo->gtp_teid.header.teid_gre);
112 memcpy(dst, src+3, 1);
113 memcpy(dst+1, src+2, 1);
114 memcpy(dst+2, src+1, 1);
115 memcpy(dst+3, src, 1);
116 }
117
118 /* NAS PDU values start */
119 e_rab->nas.header.security_header_type =
120 IntegrityProtectedCiphered;
121 e_rab->nas.header.proto_discriminator =
122 EPSMobilityManagementMessages;
123
124 /* placeholder for mac. mac value will be calculated later */
125 uint8_t mac[MAC_SIZE] = {0};
126 memcpy(e_rab->nas.header.mac, mac, MAC_SIZE);
127
128 e_rab->nas.header.seq_no = g_icsReqInfo->dl_seq_no;
129 e_rab->nas.header.message_type = AttachAccept;
130 /* TODO: Remove hardcoded value */
131 e_rab->nas.header.eps_bearer_identity = 0;
132 e_rab->nas.header.procedure_trans_identity = 1;
133
134 e_rab->nas.elements_len = ICS_REQ_NO_OF_NAS_IES;
135 e_rab->nas.elements = (nas_pdu_elements *)
136 malloc(ICS_REQ_NO_OF_NAS_IES * sizeof(nas_pdu_elements));
137
138 nas_pdu_elements *nasIEs = e_rab->nas.elements;
139 nasIEs[nasIeCnt].pduElement.attach_res = 2; /* EPS Only */
140 nasIeCnt++;
141
142 /* Refer : 24008. Section - 10.5.7.3. We want to disable TAU request coming from UE.
143 */
144//#define DISABLE_TAU 0
145#if DISABLE_TAU
146 nasIEs[nasIeCnt].pduElement.t3412 = 224;
147#else
148 nasIEs[nasIeCnt].pduElement.t3412 = 0x21; // per min
149#endif
150 nasIeCnt++;
151
152 nasIEs[nasIeCnt].pduElement.tailist.type = 1;
153 nasIEs[nasIeCnt].pduElement.tailist.num_of_elements = 0;
154
155 /* S1AP TAI mcc 123, mnc 456 : 214365 */
156 /* NAS GUTI mcc 123, mnc 456 : 216354 */
157 if ((g_icsReqInfo->tai.plmn_id.idx[1] & 0xF0) != 0xF0)
158 {
159 unsigned char x3 = g_icsReqInfo->tai.plmn_id.idx[2];
160 unsigned char x2 = g_icsReqInfo->tai.plmn_id.idx[1];
161 unsigned char x31 = x3 >> 4;
162 unsigned char x32 = x3 & 0xf;
163 unsigned char x21 = x2 >> 4;
164 unsigned char x22 = x2 & 0xf;
165 x3 = x21 | (x32 <<4);
166 x2 = (x31 << 4) | x22;
167 g_icsReqInfo->tai.plmn_id.idx[1] = x2;
168 g_icsReqInfo->tai.plmn_id.idx[2] = x3;
169 }
170
171 memcpy(&(nasIEs[nasIeCnt].pduElement.tailist.partial_list[0]),
172 &(g_icsReqInfo->tai), sizeof(g_icsReqInfo->tai));
173 nasIeCnt++;
174
175 nasIEs[nasIeCnt].pduElement.esm_msg.eps_bearer_id = 5; /* TODO: revisit */
176 nasIEs[nasIeCnt].pduElement.esm_msg.proto_discriminator = 2;
177 memcpy(&(nasIEs[nasIeCnt].pduElement.esm_msg.procedure_trans_identity), &(g_icsReqInfo->pti), 1);
178 nasIEs[nasIeCnt].pduElement.esm_msg.session_management_msgs =
179 ESM_MSG_ACTV_DEF_BEAR__CTX_REQ;
180 nasIEs[nasIeCnt].pduElement.esm_msg.eps_qos = 9;
181
182 /* TODO: Remove hardcoded value */
183 /*char apnname[4] = "apn1";
184 memcpy(&(nasIEs[nasIeCnt].esm_msg.apn.val), apnname, 4);
185 nasIEs[nasIeCnt].esm_msg.apn.len = 4;
186 */
187 nasIEs[nasIeCnt].pduElement.esm_msg.apn.len = g_icsReqInfo->apn.len;
188 memcpy(nasIEs[nasIeCnt].pduElement.esm_msg.apn.val,
189 g_icsReqInfo->apn.val, g_icsReqInfo->apn.len);
190
191
192 nasIEs[nasIeCnt].pduElement.esm_msg.pdn_addr.type = 1;
193 /*TODO : endian issue */
194 nasIEs[nasIeCnt].pduElement.esm_msg.pdn_addr.ipv4 = htonl(g_icsReqInfo->pdn_addr.ip_type.ipv4.s_addr);
195 nasIEs[nasIeCnt].pduElement.esm_msg.linked_ti.flag = 0;
196 nasIEs[nasIeCnt].pduElement.esm_msg.linked_ti.val = 0;
197 get_negotiated_qos_value(&nasIEs[nasIeCnt].pduElement.esm_msg.negotiated_qos);
198 nasIeCnt++;
199
200 /* Send the allocated GUTI to UE */
201 nasIEs[nasIeCnt].pduElement.mi_guti.odd_even_indication = 0;
202 nasIEs[nasIeCnt].pduElement.mi_guti.id_type = 6;
203
204 memcpy(&(nasIEs[nasIeCnt].pduElement.mi_guti.plmn_id),
205 &(g_icsReqInfo->tai.plmn_id), sizeof(struct PLMN));
206 nasIEs[nasIeCnt].pduElement.mi_guti.mme_grp_id = htons(g_s1ap_cfg.mme_group_id);
207 nasIEs[nasIeCnt].pduElement.mi_guti.mme_code = g_s1ap_cfg.mme_code;
208 /* TODO : Revisit, temp fix for handling detach request retransmit.
209 * M-TMSI should come from MME */
210 nasIEs[nasIeCnt].pduElement.mi_guti.m_TMSI = htonl(g_icsReqInfo->m_tmsi);
211 nasIeCnt++;
212
213 ieCnt++;
214 /* NAS PDU values end */
215 /* E-RABToBeSetupItemCtxtSUReq values end */
216
217
218 /* TODO Get value of ue_sec_capabilities
219 *
220 * value->data[ieCnt].ue_sec_capabilities = ??
221 *
222 * */
223
224
225 ieCnt++;
226
227 /* TODO: remove hard coded value */
228 /*char sec_key[32] = "abcdefghijklmnopqrstuvwxyz012345";
229 memcpy(value->data[ieCnt].sec_key, sec_key,
230 SECURITY_KEY_SIZE);
231 */
232
233 memcpy(value->data[ieCnt].val.sec_key, g_icsReqInfo->sec_key,
234 SECURITY_KEY_SIZE);
235
236 ieCnt++;
237
238 return SUCCESS;
239}
240
241
242
243/**
244* Stage specific message processing.
245*/
246static int
247icsreq_processing(struct init_ctx_req_Q_msg *g_icsReqInfo)
248{
249
250 Buffer g_ics_buffer;
251 Buffer g_s1ap_buffer;
252 Buffer g_rab1_buffer;
253 Buffer g_rab2_buffer;
254 Buffer g_nas_buffer;
255
256 unsigned char tmpStr[4];
257 struct s1ap_PDU s1apPDU;
258 uint16_t protocolIe_Id;
259 uint8_t protocolIe_criticality;
260 uint8_t initiating_msg = 0;
261 uint8_t datalen = 0;
262 //uint8_t s1ap_len_pos;
263 //uint8_t erab_len_pos;
264 //uint8_t erab_item_len_pos;
265 //uint8_t nas_len_pos;
266 uint16_t esm_len_pos;
267 uint8_t u8value = 0;
268 uint8_t mac_data_pos;
269
270 s1apPDU.procedurecode = id_InitialContextSetup;
271 s1apPDU.criticality = CRITICALITY_REJECT;
272
273 get_icsreq_protoie_value(&s1apPDU.value, g_icsReqInfo);
274
275 g_ics_buffer.pos = 0;
276
277 buffer_copy(&g_ics_buffer, &initiating_msg,
278 sizeof(initiating_msg));
279
280 buffer_copy(&g_ics_buffer, &s1apPDU.procedurecode,
281 sizeof(s1apPDU.procedurecode));
282
283 buffer_copy(&g_ics_buffer, &s1apPDU.criticality,
284 sizeof(s1apPDU.criticality));
285
286 /* TODO: revisit , why 128 (0x80) required */
287#if 0
288 s1ap_len_pos = g_ics_buffer.pos;
289 u8value = 128;
290 buffer_copy(&g_ics_buffer, &u8value, sizeof(u8value));
291
292
293
294
295 u8value = 0;
296 buffer_copy(&g_ics_buffer, &u8value, sizeof(u8value));
297#endif
298
299 g_s1ap_buffer.pos = 0;
300
301 /* TODO remove hardcoded values */
302 uint8_t chProtoIENo[3] = {0,0,6};
303 buffer_copy(&g_s1ap_buffer, chProtoIENo, 3);
304
305 /* id-MME-UE-S1AP-ID */
306 protocolIe_Id = id_MME_UE_S1AP_ID;
307 copyU16(tmpStr, protocolIe_Id);
308 buffer_copy(&g_s1ap_buffer, tmpStr, sizeof(protocolIe_Id));
309 protocolIe_criticality = CRITICALITY_REJECT;
310 buffer_copy(&g_s1ap_buffer, &protocolIe_criticality,
311 sizeof(protocolIe_criticality));
312 datalen = 2;
313 /* TODO need to add proper handling*/
314 unsigned char mme_ue_id[3];
315 datalen = copyU16(mme_ue_id, s1apPDU.value.data[0].val.mme_ue_s1ap_id);
316 buffer_copy(&g_s1ap_buffer, &datalen, sizeof(datalen));
317 buffer_copy(&g_s1ap_buffer, mme_ue_id, datalen);
318
319 /* id-eNB-UE-S1AP-ID */
320 protocolIe_Id = id_eNB_UE_S1AP_ID;
321 copyU16(tmpStr, protocolIe_Id);
322 buffer_copy(&g_s1ap_buffer, tmpStr, sizeof(protocolIe_Id));
323 buffer_copy(&g_s1ap_buffer, &protocolIe_criticality,
324 sizeof(protocolIe_criticality));
325 /* TODO needs proper handling*/
326 unsigned char enb_ue_id[3];
327 datalen = copyU16(enb_ue_id, s1apPDU.value.data[1].val.enb_ue_s1ap_id);
328 buffer_copy(&g_s1ap_buffer, &datalen, sizeof(datalen));
329 buffer_copy(&g_s1ap_buffer, enb_ue_id, datalen);
330
331 protocolIe_Id = id_uEaggregatedMaximumBitrate;
332 copyU16(tmpStr, protocolIe_Id);
333 buffer_copy(&g_s1ap_buffer, tmpStr, sizeof(protocolIe_Id));
334 buffer_copy(&g_s1ap_buffer, &protocolIe_criticality,
335 sizeof(protocolIe_criticality));
336 datalen = 10;
337
338 uint8_t maximum_bit_rate_dl = 0x18;
339 uint8_t maximum_bit_rate_ul = 0x60;
340
341 buffer_copy(&g_s1ap_buffer, &datalen, sizeof(datalen));
342
343 buffer_copy(&g_s1ap_buffer, &maximum_bit_rate_dl, sizeof(maximum_bit_rate_dl));
344
345 uint32_t temp_bitrate = htonl(g_icsReqInfo->exg_max_dl_bitrate);
346 memset(tmpStr, 0, sizeof(tmpStr));
347 memcpy(tmpStr, &temp_bitrate, sizeof(temp_bitrate));
348
349 buffer_copy(&g_s1ap_buffer, tmpStr,
350 sizeof(tmpStr));
351
352 temp_bitrate = 0;
353 temp_bitrate = htonl(g_icsReqInfo->exg_max_ul_bitrate);
354 memset(tmpStr, 0, sizeof(tmpStr));
355 memcpy(tmpStr, &temp_bitrate, sizeof(temp_bitrate));
356
357 buffer_copy(&g_s1ap_buffer, &maximum_bit_rate_ul,
358 sizeof(maximum_bit_rate_ul));
359 buffer_copy(&g_s1ap_buffer, tmpStr,
360 sizeof(tmpStr));
361
362
363 /* id-E-RABToBeSetupListCtxtSUReq */
364 ERABSetup *erab = &(s1apPDU.value.data[3].val.E_RABToBeSetupItemCtxtSUReq);
365 protocolIe_Id = id_ERABToBeSetupListCtxtSUReq;
366 copyU16(tmpStr, protocolIe_Id);
367 buffer_copy(&g_s1ap_buffer, tmpStr, sizeof(protocolIe_Id));
368 buffer_copy(&g_s1ap_buffer, &protocolIe_criticality,
369 sizeof(protocolIe_criticality));
370
371 /* Lets put this in new buffer */
372 /*rab_len_1 */
373#if 0
374 erab_len_pos = g_s1ap_buffer.pos;
375 datalen = 0;
376 buffer_copy(&g_ics_buffer, &datalen, sizeof(datalen));
377#endif
378 g_rab1_buffer.pos = 0;
379
380 buffer_copy(&g_rab1_buffer, &initiating_msg,
381 sizeof(initiating_msg));
382
383 protocolIe_Id = id_ERABToBeSetupItemCtxtSUReq;
384 copyU16(tmpStr, protocolIe_Id);
385 buffer_copy(&g_rab1_buffer, tmpStr, sizeof(protocolIe_Id));
386 buffer_copy(&g_rab1_buffer, &protocolIe_criticality,
387 sizeof(protocolIe_criticality));
388
389 /*rab_len_2 */
390#if 0
391 erab_item_len_pos = g_rab1_buffer.pos;
392 datalen = 0;
393 buffer_copy(&g_ics_buffer, &datalen, sizeof(datalen));
394#endif
395
396 /*
397 buffer_copy(&g_ics_buffer, &(erab->e_RAB_ID),
398 sizeof(erab->e_RAB_ID));
399 */
400 g_rab2_buffer.pos = 0;
401 /* TODO : Remove hardcoded value of erab id */
402 u8value =69; // 0x45 //1;
403 buffer_copy(&g_rab2_buffer, &u8value, sizeof(u8value));
404 /* TODO: Need to revisit why add 00 before qci value? */
405 u8value = 0;
406 buffer_copy(&g_rab2_buffer, &u8value, sizeof(u8value));
407 buffer_copy(&g_rab2_buffer, &(erab->e_RAB_QoS_Params.qci),
408 sizeof(erab->e_RAB_QoS_Params.qci));
409 buffer_copy(&g_rab2_buffer, &(erab->e_RAB_QoS_Params.arPrio),
410 sizeof(erab->e_RAB_QoS_Params.arPrio));
411
412 /* TODO: Revisit why we need to add 0f 80 before transport add? */
413
414 u8value = 15;
415 buffer_copy(&g_rab2_buffer, &u8value, sizeof(u8value));
416 u8value = 128;
417 buffer_copy(&g_rab2_buffer, &u8value, sizeof(u8value));
418
419 buffer_copy(&g_rab2_buffer, &(erab->transportLayerAddress),
420 sizeof(erab->transportLayerAddress));
421
422 buffer_copy(&g_rab2_buffer, &(erab->gtp_teid),
423 sizeof(erab->gtp_teid));
424
425
426 /* E_RABToBeSetupListCtxtSUReq NAS PDU start */
427 // at the end we will do.... rab2_buf + <nas_len> + nas_buffer
428
429#if 0
430 nas_len_pos = g_rab2_buffer.pos;
431 datalen = 0;
432 buffer_copy(&g_ics_buffer, &datalen, sizeof(datalen));
433#endif
434
435 nas_pdu_header *nas_hdr = &(erab->nas.header);
436
437 g_nas_buffer.pos = 0;
438 /* security header and protocol discriminator */
439 u8value = (nas_hdr->security_header_type << 4 |
440 nas_hdr->proto_discriminator);
441 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
442
443 /* mac */
444 /* placeholder for mac. mac value will be calculated later */
445 buffer_copy(&g_nas_buffer, nas_hdr->mac, MAC_SIZE);
446 mac_data_pos = g_nas_buffer.pos;
447
448 /* sequence number */
449 buffer_copy(&g_nas_buffer, &(nas_hdr->seq_no),
450 sizeof(nas_hdr->seq_no));
451
452 /* security header and protocol discriminator */
453 nas_hdr->security_header_type = Plain;
454 u8value = (nas_hdr->security_header_type << 4 |
455 nas_hdr->proto_discriminator);
456 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
457
458 /* message type */
459 buffer_copy(&g_nas_buffer, &(nas_hdr->message_type),
460 sizeof(nas_hdr->message_type));
461
462 nas_pdu_elements *ies = erab->nas.elements;
463
464 /* eps attach result */
465 buffer_copy(&g_nas_buffer, &(ies[0].pduElement.attach_res), sizeof(u8value));
466
467 /* GPRS timer */
468#define DISABLE_TAU 1
469#if DISABLE_TAU
470 uint8_t temp_timer = 224; /*e0*/
471#else
472 uint8_t temp_timer = 0x21; /*per min */
473#endif
474 //buffer_copy(&g_ics_buffer, &(ies[1].t3412), sizeof(ies[1].t3412));
475 buffer_copy(&g_nas_buffer, &temp_timer, sizeof(temp_timer));
476
477 /* TAI list */
478 u8value = 6;
479 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
480 u8value = 32; /* TODO: use value from tai list */
481 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
482 buffer_copy(&g_nas_buffer, &(ies[2].pduElement.tailist.partial_list[0].plmn_id.idx), 3);
483 buffer_copy(&g_nas_buffer, &(ies[2].pduElement.tailist.partial_list[0].tac), 2);
484
485 esm_len_pos = g_nas_buffer.pos;
486
487 /* esm message container length */
488 char tmplen[2] = {0, 0};
489 buffer_copy(&g_nas_buffer, tmplen, 2);
490
491 /* ESM message container start */
492
493 /* esm message bearer id and protocol discriminator */
494 u8value = (ies[3].pduElement.esm_msg.eps_bearer_id << 4 |
495 ies[3].pduElement.esm_msg.proto_discriminator);
496 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
497
498 /* esm message procedure identity */
499 buffer_copy(&g_nas_buffer, &(ies[3].pduElement.esm_msg.procedure_trans_identity),
500 sizeof(ies[3].pduElement.esm_msg.procedure_trans_identity));
501
502 /* esm message session management message */
503 buffer_copy(&g_nas_buffer, &(ies[3].pduElement.esm_msg.session_management_msgs),
504 sizeof(ies[3].pduElement.esm_msg.session_management_msgs));
505
506 /* eps qos */
507 datalen = 1;
508 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
509 buffer_copy(&g_nas_buffer, &(ies[3].pduElement.esm_msg.eps_qos),
510 sizeof(ies[3].pduElement.esm_msg.eps_qos));
511
512 /* apn */
513 char apn_name[25]={};
514 strncpy(apn_name, (char *)ies[3].pduElement.esm_msg.apn.val,
515 ies[3].pduElement.esm_msg.apn.len);
516 datalen = ies[3].pduElement.esm_msg.apn.len;
517 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
518 buffer_copy(&g_nas_buffer, (char *)ies[3].pduElement.esm_msg.apn.val, datalen);
519
520 /* pdn address */
521 //datalen = sizeof(ies[3].esm_msg.pdn_addr);
522 datalen = 5; //sizeof(ies[3].esm_msg.pdn_addr);
523 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
524 u8value = 1;
525 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
526 //buffer_copy(&g_ics_buffer, &(ies[3].esm_msg.pdn_addr.pdn_type), 1);
527 buffer_copy(&g_nas_buffer, &(ies[3].pduElement.esm_msg.pdn_addr.ipv4), datalen-1);
528
529 /* linked ti */
530 u8value = 0x5d; /* element id TODO: define macro or enum */
531 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
532 datalen = 1;//sizeof(ies[3].esm_msg.linked_ti);
533 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
534 buffer_copy(&g_nas_buffer, &(ies[3].pduElement.esm_msg.linked_ti), datalen);
535
536 /* negotiated qos */
537 u8value = 0x30; /* element id TODO: define macro or enum */
538 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
539 datalen = 16;//sizeof(ies[3].esm_msg.negotiated_qos);
540 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
541 buffer_copy(&g_nas_buffer, &(ies[3].pduElement.esm_msg.negotiated_qos), datalen);
542
543 /* apn ambr */
544#if 0
545 u8value = 0x5e; /* element id TODO: define macro or enum */
546 buffer_copy(&g_ics_buffer, &u8value, sizeof(u8value));
547 datalen = sizeof(ies[3].esm_msg.apn_ambr);
548 buffer_copy(&g_ics_buffer, &datalen, sizeof(datalen));
549 buffer_copy(&g_ics_buffer, &(ies[3].esm_msg.apn_ambr), datalen);
550#endif
551 /* TODO: remove hardcoded values of apn ambr */
552 char apn_ambr[8] = {0x5e, 0x06, 0x80, 0x00, 0x04, 0x05, 0x06, 0x07};
553 buffer_copy(&g_nas_buffer, apn_ambr, 8);
554
555#if 1
556 char pco_options[29] = {0x27, 0x1B, 0x80, 0x80, 0x21, 0x10, 0x03, 0x00, 0x00,0x10, 0x81, 0x06, 0x08,0x08,0x08, 0x08,0x83,0x06,0x08,0x08,0x08,0x04,0x00,0x0d, 0x04,0x08,0x08,0x08,0x08};
557 buffer_copy(&g_nas_buffer, &pco_options[0], 29);
558#endif
559
560 /* ESM message container end */
561
562 /* Copy esm container length to esm container length field */
563 uint16_t esm_datalen = g_nas_buffer.pos - esm_len_pos - 2;
564 unsigned char esm_len[2];
565 copyU16(esm_len, esm_datalen);
566 /* memcpy(&g_ics_buffer.buf[esm_len_pos], tmplen, sizeof(esm_datalen)); */
567 /*TODO: needs proper handling */
568 g_nas_buffer.buf[esm_len_pos] = esm_len[0];
569 g_nas_buffer.buf[esm_len_pos + 1] = esm_len[1];
570
571 /* EPS mobile identity GUTI */
572#if 0
573 u8value = 0x50; /* element id TODO: define macro or enum */
574 buffer_copy(&g_ics_buffer, &u8value, sizeof(u8value));
575 datalen = sizeof(ies[4].mi_guti);
576 buffer_copy(&g_ics_buffer, &datalen, sizeof(datalen));
577 buffer_copy(&g_ics_buffer, &(ies[4].mi_guti), datalen);
578#endif
579
580 u8value = 0x50; /* element id TODO: define macro or enum */
581 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
582 datalen = 11;
583 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
584
585 u8value = 246; /* TODO: remove hard coding */
586 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
587 buffer_copy(&g_nas_buffer, &(ies[4].pduElement.mi_guti.plmn_id.idx), 3);
588 buffer_copy(&g_nas_buffer, &(ies[4].pduElement.mi_guti.mme_grp_id),
589 sizeof(ies[4].pduElement.mi_guti.mme_grp_id));
590 buffer_copy(&g_nas_buffer, &(ies[4].pduElement.mi_guti.mme_code),
591 sizeof(ies[4].pduElement.mi_guti.mme_code));
592 buffer_copy(&g_nas_buffer, &(ies[4].pduElement.mi_guti.m_TMSI),
593 sizeof(ies[4].pduElement.mi_guti.m_TMSI));
594
595#if 0
596 {
597 // sending mobile identity to UE
598 /*TODO : Experiment */
599 u8value = 0x23; /* element id TODO: define macro or enum */
600 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
601 datalen = 0x05;
602 buffer_copy(&g_nas_buffer, &datalen, sizeof(datalen));
603 u8value = 0xf4; //
604 buffer_copy(&g_nas_buffer, &u8value, sizeof(u8value));
605 buffer_copy(&g_nas_buffer, &(ies[4].pduElement.mi_guti.m_TMSI),
606 sizeof(ies[4].pduElement.mi_guti.m_TMSI));
607 }
608#endif
609 /* E_RABToBeSetupListCtxtSUReq NAS PDU end */
610
611 /* Calculate mac */
612 uint8_t direction = 1;
613 uint8_t bearer = 0;
614
615 calculate_mac(g_icsReqInfo->int_key, nas_hdr->seq_no,
616 direction, bearer, &g_nas_buffer.buf[mac_data_pos],
617 g_nas_buffer.pos - mac_data_pos,
618 &g_nas_buffer.buf[mac_data_pos - MAC_SIZE]);
619
620 /* Copy nas length to nas length field */
621 //uint16_t nas_pay_len = g_nas_buffer.pos - nas_len_pos - 1;
622 log_msg(LOG_INFO, "NAS payload length %d\n", g_nas_buffer.pos);
623
624 /* start: RAB2 + NAS start */
625 /* Now lets append NAS buffer to rab2....so rab2 = rab2_buf + nas_length + nas_buf */
626 if(g_nas_buffer.pos <= 127 )
627 {
628 /* datalen = g_nas_buffer.pos - nas_len_pos - 1; */
629 datalen = g_nas_buffer.pos;
630 buffer_copy(&g_rab2_buffer, &datalen, sizeof(datalen));
631 }
632 else
633 {
634 uint16_t nas_pay_len = g_nas_buffer.pos | 0x8000; // set MSB to 1
635 unsigned char lenStr[2];
636 lenStr[0] = nas_pay_len >> 8;
637 lenStr[1] = nas_pay_len & 0xff;
638 buffer_copy(&g_rab2_buffer, lenStr, sizeof(lenStr));
639 }
640 buffer_copy(&g_rab2_buffer, &g_nas_buffer.buf[0], g_nas_buffer.pos);
641 /* end : RAB2 + NAS done */
642
643 log_msg(LOG_INFO, "RAB2 payload length %d\n", g_rab2_buffer.pos);
644 /* Now lets append rab2 to rab1 */
645 if(g_rab2_buffer.pos <= 127)
646 {
647 datalen = g_rab2_buffer.pos;
648 buffer_copy(&g_rab1_buffer, &datalen, sizeof(datalen));
649 }
650 else
651 {
652 uint16_t rab2_pay_len = g_rab2_buffer.pos | 0x8000; // set MSB to 1
653 unsigned char lenStr[2];
654 lenStr[0] = rab2_pay_len >> 8;
655 lenStr[1] = rab2_pay_len & 0xff;
656 buffer_copy(&g_rab1_buffer, lenStr, sizeof(lenStr));
657 }
658 buffer_copy(&g_rab1_buffer, &g_rab2_buffer.buf[0], g_rab2_buffer.pos);
659 /* rab1 + rab2 is appended */
660 // rab1 is combined now ...
661
662 /*g_s1ap_buffer is having rab appended to it.. */
663
664 log_msg(LOG_INFO, "RAB1 payload length %d\n", g_rab1_buffer.pos);
665 if(g_rab1_buffer.pos <= 127)
666 {
667 datalen = g_rab1_buffer.pos;
668 buffer_copy(&(g_s1ap_buffer), &datalen, sizeof(datalen));
669 }
670 else
671 {
672 uint16_t rab1_pay_len = g_rab1_buffer.pos | 0x8000; // set MSB to 1
673 unsigned char lenStr[2];
674 lenStr[0] = rab1_pay_len >> 8;
675 lenStr[1] = rab1_pay_len & 0xff;
676 buffer_copy(&g_s1ap_buffer, lenStr, sizeof(lenStr));
677 }
678 buffer_copy(&g_s1ap_buffer, &g_rab1_buffer.buf[0], g_rab1_buffer.pos);
679 /* RAB is appended to s1ap payload now */
680
681 /* id-UESecurityCapabilities */
682 char ue_sec_capab[5] = {0x1c, 0x00, 0x0c, 0x00, 0x00};
683 protocolIe_Id = id_UESecurityCapabilities;
684 copyU16(tmpStr, protocolIe_Id);
685 buffer_copy(&g_s1ap_buffer, tmpStr, sizeof(protocolIe_Id));
686 protocolIe_criticality = CRITICALITY_REJECT;
687 buffer_copy(&g_s1ap_buffer, &protocolIe_criticality,
688 sizeof(protocolIe_criticality));
689 datalen = 5;
690 buffer_copy(&g_s1ap_buffer, &datalen, sizeof(datalen));
691 buffer_copy(&g_s1ap_buffer, ue_sec_capab, 5);
692
693 protocolIe_Id = id_SecurityKey;
694 copyU16(tmpStr, protocolIe_Id);
695 buffer_copy(&g_s1ap_buffer, tmpStr, sizeof(protocolIe_Id));
696 protocolIe_criticality = CRITICALITY_REJECT;
697 buffer_copy(&g_s1ap_buffer, &protocolIe_criticality,
698 sizeof(protocolIe_criticality));
699 datalen = SECURITY_KEY_SIZE;
700 buffer_copy(&g_s1ap_buffer, &datalen, sizeof(datalen));
701 buffer_copy(&g_s1ap_buffer, s1apPDU.value.data[5].val.sec_key,
702 SECURITY_KEY_SIZE);
703
704 /* Copy length to s1ap length field */
705 //datalen = g_s1ap_buffer.pos - s1ap_len_pos - 1;
706 //uint16_t s1aplen = g_s1ap_buffer.pos - s1ap_len_pos - 1;
707 log_msg(LOG_INFO, "S1AP payload length %d\n", g_s1ap_buffer.pos);
708 uint16_t s1aplen = g_s1ap_buffer.pos;
709 if(s1aplen <= 127 )
710 {
711 datalen = s1aplen;
712 buffer_copy(&g_ics_buffer, &datalen, sizeof(datalen));
713 }
714 else
715 {
716 s1aplen = g_s1ap_buffer.pos | 0x8000; // set MSB to 1
717 unsigned char lenStr[2];
718 lenStr[0] = s1aplen >> 8;
719 lenStr[1] = s1aplen & 0xff;
720 buffer_copy(&g_ics_buffer, lenStr, sizeof(lenStr));
721 }
722
723 /* this is my final s1ap buffer */
724 buffer_copy(&g_ics_buffer, &g_s1ap_buffer.buf[0], g_s1ap_buffer.pos);
725
726 free(s1apPDU.value.data[3].val.E_RABToBeSetupItemCtxtSUReq.nas.elements);
727 free(s1apPDU.value.data);
728
729 send_sctp_msg(g_icsReqInfo->enb_fd, g_ics_buffer.buf, g_ics_buffer.pos, 1);
730 log_msg(LOG_INFO,"Initial Context Setup Request sent successfully\n");
731 return SUCCESS;
732}
733
734void*
735icsreq_handler(void *data)
736{
737 log_msg(LOG_INFO, "icsreq handler ready.\n");
738
739
740 icsreq_processing((struct init_ctx_req_Q_msg *)data);
741
742
743 return NULL;
744}