blob: 9732c6dc0e53ff72f8984165dfc3701431793bf6 [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
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <string.h>
23#include <pthread.h>
24
25#include "options.h"
26#include "ipc_api.h"
27#include "main.h"
28#include "s1ap.h"
29#include "s1ap_config.h"
30#include "sctp_conn.h"
31#include "s1ap_structs.h"
32#include "s1ap_msg_codes.h"
33#include "s1ap_ie.h"
34#include "ProtocolIE-ID.h"
35#include "ProtocolIE-Field.h"
36static void
37parse_erab_pdu(char *msg, int nas_msg_len, struct eRAB_elements *erab)
38{
39 //struct eRAB_header *header = (struct eRAB*)msg;
40
41 //char *ie = msg + 5; /*ID(2)+crit(1)+len(1)+mistry(1)*/
42
43 /*TODO: write parse_IEs for erab IEs here going ahead*/
44 /*For now copying directly as it is single structure*/
45 char *ie = msg + 5; /*ID(2)+crit(1)+len(1)*/
46
47 erab->no_of_elements = 1;
48 erab->elements = (union eRAB_IE*)calloc(sizeof(union eRAB_IE), 1);
49 if(NULL == erab->elements) {
50 log_msg(LOG_ERROR, "Memory alloc failed\n");
51 exit(-1);
52 }
53
54 erab->elements[0].su_res.eRAB_id = *ie;
55 ++ie;
56 ++ie; //what is this identify.
57 memcpy(&(erab->elements[0].su_res.transp_layer_addr), ie, sizeof(unsigned int));
58 erab->elements[0].su_res.transp_layer_addr = ntohl(erab->elements[0].su_res.transp_layer_addr);
59 log_msg(LOG_INFO, "eRAB - Transport layer address : %d\n", erab->elements[0].su_res.transp_layer_addr);
60 //ntohl ??
61 ie+=sizeof(unsigned int);
62
63 memcpy(&(erab->elements[0].su_res.gtp_teid), ie, sizeof(unsigned int));
64 erab->elements[0].su_res.gtp_teid = ntohl(erab->elements[0].su_res.gtp_teid);
65 log_msg(LOG_INFO, "eRAB - Teid : %d\n", erab->elements[0].su_res.gtp_teid);
66 //ntohl ??
67}
68
69void
70parse_nas_pdu(char *msg, int nas_msg_len, struct nasPDU *nas,
71 unsigned short proc_code)
72{
73 log_msg(LOG_INFO, "NAS PDU proc code: %u\n", proc_code);
74
75 unsigned short msg_len = nas_msg_len;
76
77 char *buffer = NULL;
78 log_msg(LOG_INFO, "NAS PDU msg: %s\n", msg_to_hex_str(msg, msg_len, &buffer));
79 log_buffer_free(&buffer);
80
81#if 0
82 if(S1AP_UL_NAS_TX_MSG_CODE == proc_code) {
83 /*check whether there is security header*/
84 unsigned char header_type;
85 memcpy(&header_type, msg+1, 1);
86 header_type >>= 4;
87 if(0 == header_type) { /*not security header*/
88 log_msg(LOG_INFO, "No security header\n");
89 memcpy(&(nas->header), msg+1, 2);/*copy only till msg type*/
90 } else {
91 log_msg(LOG_INFO, "Security header\n");
92 /*now for esm resp, there is procedure tx identity, why the hell it was not there before.*/
93 /*one more donkey logic, do something!!*/
94 if(4 == header_type || ((7 == (*(msg+7) & 7)))) {
95 memcpy(&(nas->header), msg+7, 2);/*copy only till msg type*/
96 offset = 9;
97 } else {
98 unsigned char tmp;
99 memcpy(&(nas->header.message_type), msg+9, 1);/*copy only till msg type*/
100 memcpy(&(tmp), msg+7, 1);/*copy only till msg type*/
101 nas->header.security_header_type = tmp;
102 offset = 10;
103 }
104 }
105 } else {
106 memcpy(&(nas->header), msg+2, sizeof(nas_pdu_header));
107 }
108
109 if(S1AP_UL_NAS_TX_MSG_CODE == proc_code) {
110 /*check whether there is security header*/
111 unsigned char header_type = 0;
112
113 memcpy(&header_type, msg+1, 1);
114 header_type >>= 4;
115 if(0 == header_type) { /*not security header*/
116 log_msg(LOG_INFO, "No security header\n");
117 memcpy(&(nas->header), msg+1, 2);/*copy only till msg type*/
118 } else {
119 log_msg(LOG_INFO, "Security header\n");
120 /*now for esm resp, there is procedure tx identity, why the hell it was not there before.*/
121 /*one more donkey logic, do something!!*/
122 if(4 == header_type || ((7 == (*(msg+7) & 7)))) {
123 log_msg(LOG_INFO, "header == 4 || 7\n");
124 if(header_type == 4 || header_type == 2) {
125 log_msg(LOG_INFO, "security - cihpered\n");
126 memcpy(&(nas->header), msg+7, 2);/*copy only till msg type*/
127 offset = 9;
128 }
129 else {
130 log_msg(LOG_INFO, "security - noned\n");
131 memcpy(&(nas->header), msg+1, 2);/*copy only till msg type*/
132 offset = 3;
133 }
134 } else {
135 unsigned char tmp;
136 memcpy(&(nas->header.message_type), msg+9, 1);/*copy only till msg type*/
137 memcpy(&(tmp), msg+7, 1);/*copy only till msg type*/
138 nas->header.security_header_type = tmp;
139 offset = 10;
140 }
141 }
142 } else if (S1AP_INITIAL_UE_MSG_CODE == proc_code ) {
143#endif
144
145 nas_pdu_header_sec nas_header_sec;
146 nas_pdu_header_short nas_header_short;
147 nas_pdu_header_long nas_header_long;
148
149 unsigned char sec_header_type;
150 unsigned char protocol_discr;
151
152 sec_header_type = msg[0] >> 4;
153 protocol_discr = msg[0] & 0x0F;
154 unsigned char is_ESM = ((unsigned short)protocol_discr == 0x02); // see TS 24.007
155 log_msg(LOG_INFO, "Security header=%d\n", sec_header_type);
156 log_msg(LOG_INFO, "Protocol discriminator=%d\n", protocol_discr);
157 log_msg(LOG_INFO, "is_ESM=%d\n", is_ESM);
158
159 if(0 != sec_header_type) { /*security header*/
160 log_msg(LOG_INFO, "Security header\n");
161
162 memcpy(&nas_header_sec, msg, sizeof(nas_pdu_header_sec));
163
164 char *buffer = NULL;
165 log_msg(LOG_INFO, "mac=%s\n", msg_to_hex_str((char *)nas_header_sec.mac, MAC_SIZE, &buffer));
166 log_buffer_free(&buffer);
167
168 log_msg(LOG_INFO, "seq no=%x\n", nas_header_sec.seq_no);
169 msg += 6;
170
171 sec_header_type = msg[0] >> 4;
172 protocol_discr = msg[0] & 0x0F;
173 unsigned char is_ESM = ((unsigned short)protocol_discr == 0x02); // see TS 24.007
174 log_msg(LOG_INFO, "Security header=%d\n", sec_header_type);
175 log_msg(LOG_INFO, "Protocol discriminator=%d\n", protocol_discr);
176 log_msg(LOG_INFO, "is_ESM=%d\n", is_ESM);
177 if (is_ESM) {
178 log_msg(LOG_INFO, "NAS PDU is ESM\n");
179 memcpy(&nas_header_long, msg, sizeof(nas_header_long)); /*copy only till msg type*/
180 msg += 3;
181
182 nas->header.security_header_type = nas_header_long.security_header_type;
183 nas->header.proto_discriminator = nas_header_long.proto_discriminator;
184 nas->header.procedure_trans_identity = nas_header_long.procedure_trans_identity;
185 nas->header.message_type = nas_header_long.message_type;
186 } else {
187 log_msg(LOG_INFO, "NAS PDU is EMM\n");
188 memcpy(&nas_header_short, msg, sizeof(nas_header_short)); /*copy only till msg type*/
189 msg += 2;
190
191 nas->header.security_header_type = nas_header_short.security_header_type;
192 nas->header.proto_discriminator = nas_header_short.proto_discriminator;
193 nas->header.message_type = nas_header_short.message_type;
194 }
195 } else {
196 log_msg(LOG_INFO, "No security header\n");
197 memcpy(&nas_header_short, msg, sizeof(nas_header_short)); /*copy only till msg type*/
198 msg += 2;
199
200 nas->header.security_header_type = nas_header_short.security_header_type;
201 nas->header.proto_discriminator = nas_header_short.proto_discriminator;
202 nas->header.message_type = nas_header_short.message_type;
203 }
204
205
206 log_msg(LOG_INFO, "Nas msg type: %X\n", nas->header.message_type);
207
208 switch(nas->header.message_type) {
209 case NAS_ESM_RESP:{
210 log_msg(LOG_INFO, "NAS_ESM_RESP recvd\n");
211
212 unsigned char element_id;
213 memcpy(&element_id, msg, 1);
214 msg++;
215 nas->elements_len +=1;
216
217 nas->elements = calloc(sizeof(nas_pdu_elements), 2);
218 //if(NULL == nas.elements)...
219
220 memcpy(&(nas->elements[0].apn.len), msg, 1);
221 msg++;
222 memcpy(nas->elements[0].apn.val, msg, nas->elements[0].apn.len);
223 log_msg(LOG_INFO, "APN name - %s\n", nas->elements[0].apn.val);
224 break;
225 }
226
227 case NAS_SEC_MODE_COMPLETE:
228 log_msg(LOG_INFO, "NAS_SEC_MODE_COMPLETE recvd\n");
229 break;
230
231 case NAS_AUTH_RESP:
232 log_msg(LOG_INFO, "NAS_AUTH_RESP recvd\n");
233 nas->elements_len = 1;
234 nas->elements = calloc(sizeof(nas_pdu_elements), 5);
235 //if(NULL == nas.elements)...
236 unsigned short len = get_length(&msg);
237 memcpy(&(nas->elements[0].auth_resp), msg, sizeof(struct XRES));
238
239 break;
240
241/* case NAS_AUTH_FAILURE:
242 nas->elements_len = 1;
243 nas->elements = calloc(sizeof(nas_pdu_elements), 1);
244 //if(NULL == nas.elements)...
245 char err = *(char*)(msg);
246 if(err == AUTH_SYNC_FAILURE)
247 {
248 log_msg(LOG_INFO, "AUTH Sync Failure. Start Re-Sync");
249 memcpy(&(nas->elements[0].auth_fail_resp), msg + 2, sizeof(struct AUTS));
250 }
251 else
252 {
253 log_msg(LOG_ERROR, "Authentication Failure. Mac Failure");
254 }
255
256 break;
257*/
258 case NAS_ATTACH_REQUEST:{
259 log_msg(LOG_INFO, "NAS_ATTACH_REQUEST recvd\n");
260 //msg += offset;
261 //short offset = 0;
262 unsigned char tmp = msg[0];
263 nas->header.security_encryption_algo = (tmp & 0xF0) >> 4;
264 nas->header.security_integrity_algo = tmp & 0x0F;
265 msg++;
266
267 nas->elements_len = 6;
268 nas->elements = calloc(sizeof(nas_pdu_elements), 6);
269 //if(NULL == nas.elements)...
270
271 /*EPS mobility identity*/
272 //memcpy(&(nas->elements[0].IMSI), msg+6, BINARY_IMSI_LEN);
273 /*TODO: This encoding/decoding has issue with sprirent and ng40. IMSI
274 * is packed differently.*/
275 /*Code working with ng40 */
276 unsigned short imsi_len = get_length(&msg);
277 log_msg(LOG_INFO, "IMSI len=%u - %u\n", imsi_len, BINARY_IMSI_LEN);
278 memcpy(&(nas->elements[0].IMSI), msg, imsi_len);
279 msg += imsi_len;
280
281 /*Code working with sprirent and Polaris*/
282 /*
283 memcpy(&(nas->elements[0].IMSI), msg+5, BINARY_IMSI_LEN);
284 offset = 5 + BINARY_IMSI_LEN ;
285 */
286
287 char *buffer = NULL;
288 log_msg(LOG_INFO, "IMSI=%s [to be read nibble-swapped]\n",
289 msg_to_hex_str((char *)nas->elements[0].IMSI, imsi_len, &buffer));
290 log_buffer_free(&buffer);
291
292 /*UE network capacity*/
293 nas->elements[1].ue_network.len = msg[0];
294 msg++;
295 memcpy((nas->elements[1].ue_network.capab), msg, nas->elements[1].ue_network.len);
296 msg += nas->elements[1].ue_network.len;
297
298 /*ESM msg container*/
299 len = msg[0] << 8 | msg[1];
300 msg += 2;
301 log_msg(LOG_INFO, "len=%x\n", len);
302 log_msg(LOG_INFO, "msg[0]=%x\n", msg[0]);
303 nas->elements[5].pti = msg[1];
304 unsigned char val = msg[4];
305 log_msg(LOG_INFO, "pti=%x\n", nas->elements[5].pti);
306 log_msg(LOG_INFO, "val=%x\n", val);
307 /*ESM message header len is 4: bearer_id_flags(1)+proc_tx_id(1)+msg_id(1)
308 * +pdn_type(1)*/
309 /*element id 13(1101....) = "esm required" flag*/
310 nas->elements[2].esm_info_tx_required = false;
311 if(13 == (val>>4)) {
312 nas->elements[2].esm_info_tx_required = true;
313 if(val & 1) {
314 nas->elements[2].esm_info_tx_required = true;
315 }
316 }
317 msg += len;
318
319 /*DRX parameter*/
320 msg += 3;
321
322 /*MS network capability*/
323 nas->elements[4].ms_network.element_id = msg[0];
324 msg++;
325 nas->elements[4].ms_network.len = msg[0];
326 msg++;
327 memcpy(nas->elements[4].ms_network.capab, msg,
328 nas->elements[4].ms_network.len);
329 log_msg(LOG_INFO, "element_id=%x\n", nas->elements[4].ms_network.element_id);
330 log_msg(LOG_INFO, "len=%x\n", nas->elements[4].ms_network.len);
331 log_msg(LOG_INFO, "network.capab=%s\n", msg_to_hex_str((char *)nas->elements[4].ms_network.capab, nas->elements[4].ms_network.len, &buffer));
332 log_buffer_free(&buffer);
333
334 break;
335 }
336
337 case NAS_ATTACH_COMPLETE:
338 log_msg(LOG_INFO, "NAS_ATTACH_COMPLETE recvd\n");
339 /*Other than error check there seems no information to pass to mme. Marking TODO for protocol study*/
340 break;
341
342 case NAS_DETACH_REQUEST: {
343 log_msg(LOG_INFO, "NAS_DETACH_REQUEST recvd\n");
344 nas->elements_len = 1;
345 nas->elements = calloc(sizeof(nas_pdu_elements), 1);
346
347 /*EPS mobility identity*/
348 memcpy(&(nas->elements[0].mi_guti), msg + 11, sizeof(guti));
349 log_msg(LOG_INFO, "M-TMSI - %d\n", nas->elements[0].mi_guti.m_TMSI);
350 break;
351 }
352
353 case NAS_DETACH_ACCEPT: {
354 log_msg(LOG_INFO, "NAS_DETACH_ACCEPT recvd\n");
355 nas->elements_len = 1;
356 nas->elements = calloc(sizeof(nas_pdu_elements), 1);
357
358 /*EPS mobility identity*/
359 memcpy(&(nas->elements[0].mi_guti), msg + 11, sizeof(guti));
360 log_msg(LOG_INFO, "M-TMSI - %d\n", nas->elements[0].mi_guti.m_TMSI);
361 break;
362 }
363
364 default:
365 log_msg(LOG_ERROR, "Unknown NAS IE type- 0x%x\n", nas->header.message_type);
366 break;
367
368 }
369}
370
371
372int
373parse_IEs(char *msg, struct proto_IE *proto_ies, unsigned short proc_code)
374{
375 unsigned short int no_of_IEs=0;
376
377 //short data_size=0;
378 //msg +=1;
379 //memcpy(&data_size, msg, 1);
380
381 //msg +=2;
382 memcpy(&no_of_IEs, msg, 2);
383 //no_of_IEs=msg[0];
384 no_of_IEs = ntohs(no_of_IEs);
385
386 /*Dumb logic....protocol or is creepy. Len sometimes comes in 3 bytes. How to know that??*/
387 if(0 == no_of_IEs) {
388 ++msg;
389 memcpy(&no_of_IEs, msg, 2);
390 no_of_IEs = ntohs(no_of_IEs);
391 }
392
393 log_msg(LOG_INFO, "No. of IEs = %d\n", no_of_IEs);
394 proto_ies->no_of_IEs = no_of_IEs;
395 proto_ies->data = calloc(sizeof(struct proto_IE_data), no_of_IEs);
396 //alloc fail chk
397 msg+=2;
398
399 for(int i=0; i < no_of_IEs; ++i) {
400 struct proto_IE_data *ie = &(proto_ies->data[i]);
401 unsigned short IE_type, IE_data_len = 0;
402
403 memcpy(&IE_type, msg, sizeof(short int));
404 IE_type = ntohs(IE_type);
405 ie->IE_type = IE_type;
406 msg +=2;//next to ie type
407 msg +=1;//next to criticality
408
409 IE_data_len = get_length(&msg);
410 log_msg(LOG_INFO, "IE [%d]: type = %d\n", i, IE_type);
411 log_msg(LOG_INFO, "IE [%d]: data len= %x - %u\n", i, IE_data_len, IE_data_len);
412
413 char *buffer = NULL;
414 log_msg(LOG_INFO, "IE [%d]: value= %s\n", i, msg_to_hex_str(msg, IE_data_len, &buffer));
415 log_buffer_free(&buffer);
416
417 /*Based on IE_Type call the parser to read IE info*/
418 /*TODO: optimize with function ptr etc.*/
419 switch(IE_type) {
420 case S1AP_IE_GLOBAL_ENB_ID:
421 log_msg(LOG_INFO, "IE [%d]: parse global eNB ID\n", i);
422 ie_parse_global_enb_id(msg+6, IE_data_len);
423 break;
424
425 case S1AP_IE_ENB_NAME:
426 log_msg(LOG_INFO, "IE [%d]: parse global eNB name\n", i);
427 ie_parse_enb_name(msg, IE_data_len);
428 break;
429
430 case S1AP_IE_SUPPORTED_TAS:
431 break;
432
433 case S1AP_IE_DEF_PAGING_DRX:
434 break;
435
436 case S1AP_IE_MME_UE_ID:{
437 ie->val.mme_ue_s1ap_id = decode_int_val((unsigned char *)msg,
438 IE_data_len);
439 log_msg(LOG_INFO, "IE [%d]: parse MME_UE_S1AP_ID - %d\n", i,
440 ie->val.mme_ue_s1ap_id);
441 break;
442 }
443
444 case S1AP_IE_ENB_UE_ID:{
445 ie->val.enb_ue_s1ap_id = decode_int_val((unsigned char *)msg,
446 IE_data_len);
447 log_msg(LOG_INFO, "IE [%d]: parse ENB_UE_S1AP_ID - %d\n", i,
448 ie->val.enb_ue_s1ap_id);
449 break;
450 }
451
452 case S1AP_IE_TAI:{
453 log_msg(LOG_INFO, "IE [%d]: TAI parse\n", i);
454 memcpy(&(ie->val.tai), msg+1, sizeof(struct TAI));
455 log_msg(LOG_INFO, "IE [%d]: plmn-%x %x %x, tac-%d\n", i,
456 ie->val.tai.plmn_id.idx[0],
457 ie->val.tai.plmn_id.idx[1], ie->val.tai.plmn_id.idx[2],
458 ie->val.tai.tac);
459 break;
460 }
461
462 case S1AP_IE_UTRAN_CGI:{
463 log_msg(LOG_INFO, "IE [%d]: EUTRAN CGI\n", i);
464 memset(&(ie->val.utran_cgi), 0, sizeof(struct CGI));
465 memcpy(&(ie->val.utran_cgi), msg+1, sizeof(struct CGI));
466 log_msg(LOG_INFO, "IE [%d]: plmn-%x %x %x, cell-%d\n", i,
467 ie->val.utran_cgi.plmn_id.idx[0],
468 ie->val.utran_cgi.plmn_id.idx[1], ie->val.utran_cgi.plmn_id.idx[2],
469 ie->val.utran_cgi.cell_id);
470 break;
471 }
472
473 case S1AP_IE_NAS_PDU: {
474 log_msg(LOG_INFO, "IE [%d]: NAS msg type parsed = %x\n", i,
475 ie->val.nas.header.message_type);
476 parse_nas_pdu(msg, IE_data_len, &ie->val.nas, proc_code);
477 break;
478 }
479
480 case S1AP_IE_RRC_EST_CAUSE: {
481 log_msg(LOG_INFO, "IE [%d]: parse RRC establishment code - %d\n", i,
482 ie->val.rrc_est_cause);
483 break;
484 }
485
486 case S1AP_ERAB_SETUP_CTX_SUR:
487 log_msg(LOG_INFO, "IE [%d]: parse S1AP_ERAB_SETUP_CTX_SUR parse_erab_pdu \n", i);
488 parse_erab_pdu(msg, IE_data_len, &ie->val.erab);
489 break;
490
491 default:
492 log_msg(LOG_INFO, "IE [%d]: Check IE type %d\n", i, IE_type);
493 break;
494 }
495
496 msg += (IE_data_len);
497 if(128 == IE_data_len) ++msg;//TODO: byte size issue. chk thi.
498 }
499 return 0;
500}
501
502int convertToInitUeProtoIe(InitiatingMessage_t *msg, struct proto_IE* proto_ies)
503{
504 proto_ies->procedureCode = msg->procedureCode;
505 proto_ies->criticality = msg->criticality;
506 int no_of_IEs = 0;
507
508 if(msg->value.present == InitiatingMessage__value_PR_InitialUEMessage)
509 {
510 ProtocolIE_Container_129P32_t* protocolIes = &msg->value.choice.InitialUEMessage.protocolIEs;
511 no_of_IEs = protocolIes->list.count;
512 proto_ies->no_of_IEs = no_of_IEs;
513
514 log_msg(LOG_INFO, "No of IEs = %d\n", no_of_IEs);
515 proto_ies->data = calloc(sizeof(struct proto_IE_data), no_of_IEs);
516 if(proto_ies->data == NULL)
517 {
518 log_msg(LOG_ERROR,"Malloc failed for protocol IE.");
519 return -1;
520 }
521 for (int i = 0; i < protocolIes->list.count; i++) {
522 InitialUEMessage_IEs_t *ie_p;
523 ie_p = protocolIes->list.array[i];
524 switch(ie_p->id) {
525 case ProtocolIE_ID_id_eNB_UE_S1AP_ID:
526 {
527 ENB_UE_S1AP_ID_t *s1apENBUES1APID_p = NULL;
528 if(InitialUEMessage_IEs__value_PR_ENB_UE_S1AP_ID == ie_p->value.present)
529 {
530 s1apENBUES1APID_p = &ie_p->value.choice.ENB_UE_S1AP_ID;
531 }
532
533 if (s1apENBUES1APID_p == NULL) {
534 log_msg (LOG_ERROR, "Decoding of IE eNB_UE_S1AP_ID failed\n");
535 return -1;
536 }
537
538 log_msg(LOG_DEBUG, "ENB UE S1ap ID decode Success\n", no_of_IEs);
539 proto_ies->data[i].IE_type = S1AP_IE_ENB_UE_ID;
540 memcpy(&proto_ies->data[i].val.enb_ue_s1ap_id, s1apENBUES1APID_p, sizeof(ENB_UE_S1AP_ID_t));
541 s1apENBUES1APID_p = NULL;
542 } break;
543 case ProtocolIE_ID_id_NAS_PDU:
544 {
545 NAS_PDU_t *s1apNASPDU_p = NULL;
546 if(InitialUEMessage_IEs__value_PR_NAS_PDU == ie_p->value.present)
547 {
548 s1apNASPDU_p = &ie_p->value.choice.NAS_PDU;
549 }
550
551 if (s1apNASPDU_p == NULL) {
552 log_msg (LOG_ERROR, "Decoding of IE NAS PDU failed\n");
553 return -1;
554 }
555
556 log_msg(LOG_DEBUG, "NAS PDU decode Success\n", no_of_IEs);
557 proto_ies->data[i].IE_type = S1AP_IE_NAS_PDU;
558 parse_nas_pdu((char*)s1apNASPDU_p->buf, s1apNASPDU_p->size,
559 &proto_ies->data[i].val.nas, msg->procedureCode);
560 s1apNASPDU_p = NULL;
561 } break;
562 case ProtocolIE_ID_id_TAI:
563 {
564 TAI_t *s1apTAI_p = NULL;
565 if(InitialUEMessage_IEs__value_PR_TAI == ie_p->value.present)
566 {
567 s1apTAI_p = &ie_p->value.choice.TAI;
568 }
569
570 if (s1apTAI_p == NULL) {
571 log_msg (LOG_ERROR, "Decoding of IE TAI failed\n");
572 return -1;
573 }
574
575 log_msg(LOG_DEBUG, "TAI decode Success\n", no_of_IEs);
576 proto_ies->data[i].IE_type = S1AP_IE_TAI;
577 memcpy(&proto_ies->data[i].val.tai.tac, s1apTAI_p->tAC.buf, s1apTAI_p->tAC.size);
578 memcpy(&proto_ies->data[i].val.tai.plmn_id,
579 s1apTAI_p->pLMNidentity.buf, s1apTAI_p->pLMNidentity.size);
580 s1apTAI_p = NULL;
581 } break;
582 case ProtocolIE_ID_id_EUTRAN_CGI:
583 {
584 EUTRAN_CGI_t* s1apCGI_p = NULL;;
585 if(InitialUEMessage_IEs__value_PR_EUTRAN_CGI == ie_p->value.present)
586 {
587 s1apCGI_p = &ie_p->value.choice.EUTRAN_CGI;
588 }
589
590 if (s1apCGI_p == NULL) {
591 log_msg (LOG_ERROR, "Decoding of IE CGI failed\n");
592 return -1;
593 }
594
595 log_msg(LOG_DEBUG, "CGI decode Success\n", no_of_IEs);
596 proto_ies->data[i].IE_type = S1AP_IE_UTRAN_CGI;
597 memcpy(&proto_ies->data[i].val.utran_cgi.cell_id,
598 s1apCGI_p->cell_ID.buf, s1apCGI_p->cell_ID.size);
599 memcpy(&proto_ies->data[i].val.utran_cgi.plmn_id.idx,
600 s1apCGI_p->pLMNidentity.buf, s1apCGI_p->pLMNidentity.size);
601 s1apCGI_p = NULL;
602 } break;
603 case ProtocolIE_ID_id_RRC_Establishment_Cause:
604 {
605 RRC_Establishment_Cause_t *s1apRRCEstCause_p;
606 if(InitialUEMessage_IEs__value_PR_RRC_Establishment_Cause == ie_p->value.present)
607 {
608 s1apRRCEstCause_p = &ie_p->value.choice.RRC_Establishment_Cause;
609 }
610
611 if (s1apRRCEstCause_p == NULL) {
612 log_msg (LOG_ERROR, "Decoding of IE RRC Cause failed\n");
613 return -1;
614 }
615
616 log_msg(LOG_DEBUG, "RRC Cause decode Success\n", no_of_IEs);
617 proto_ies->data[i].IE_type = S1AP_IE_RRC_EST_CAUSE;
618 proto_ies->data[i].val.rrc_est_cause = (enum ie_RRC_est_cause) *s1apRRCEstCause_p;
619 s1apRRCEstCause_p = NULL;
620 } break;
621 default:
622 {
623 log_msg(LOG_WARNING, "Unhandled IE %d", ie_p->id);
624 }
625 }
626 }
627 }
628
629 return 0;
630}
631
632static int
633init_ue_msg_handler(InitiatingMessage_t *msg, int enb_fd)
634{
635 //TODO: use static instead of synamic for perf.
636 struct proto_IE proto_ies;
637
638 log_msg(LOG_INFO, "S1AP_INITIAL_UE_MSG msg: \n");
639
640 convertToInitUeProtoIe(msg, &proto_ies);
641 /*Check nas message type*/
642 //TODO: check through all proto IEs for which is nas
643 //currentlyy hard coding to 2 looking at packets
644 log_msg(LOG_INFO, "NAS msg type parsed = %x\n", proto_ies.data[1].val.nas.header.message_type);
645 switch(proto_ies.data[1].val.nas.header.message_type) {
646 case NAS_ATTACH_REQUEST:
647 s1_init_ue_handler(&proto_ies, enb_fd);
648 break;
649
650 case NAS_DETACH_REQUEST:
651 detach_stage1_handler(&proto_ies, true);
652 break;
653
654 case NAS_DETACH_ACCEPT:
655 detach_accept_from_ue_handler(&proto_ies, true);
656 break;
657 }
658
659 free(proto_ies.data);
660 //TODO: free IEs
661 return SUCCESS;
662}
663
664static int
665UL_NAS_msg_handler(InitiatingMessage_t *msg, int enb_fd)
666{
667 //TODO: use static instead of synamic for perf.
668 struct proto_IE proto_ies;
669
670 log_msg(LOG_INFO, "S1AP_UL_NAS_TX_MSG msg \n");
671
672 convertUplinkNasToProtoIe(msg, &proto_ies);
673
674 /*Check nas message type*/
675 //TODO: check through all proto IEs for which is nas
676 //currentlyy hard coding to 2 looking at packets
677 log_msg(LOG_INFO, "NAS msg type = %x\n", proto_ies.data[2].val.nas.header.message_type);
678 switch(proto_ies.data[2].val.nas.header.message_type) {
679 case NAS_AUTH_RESP:
680 s1_auth_resp_handler(&proto_ies);
681 break;
682/*
683 case NAS_AUTH_FAILURE:
684 s1_auth_fail_handler(&proto_ies);
685 break;
686*/
687 case NAS_ATTACH_REQUEST:
688 s1_init_ue_handler(&proto_ies, enb_fd);
689 break;
690
691 case NAS_SEC_MODE_COMPLETE:
692 s1_secmode_resp_handler(&proto_ies);
693 break;
694
695/* case NAS_ESM_RESP:
696 s1_esm_resp_handler(&proto_ies);
697 break;
698*/
699 case NAS_ATTACH_COMPLETE:
700 s1_attach_complete_handler(&proto_ies);
701 break;
702
703 case NAS_DETACH_REQUEST:
704 detach_stage1_handler(&proto_ies, false);
705 break;
706
707 case NAS_DETACH_ACCEPT:
708 detach_accept_from_ue_handler(&proto_ies, false);
709 break;
710 }
711
712 //TODO: free IEs
713 free(proto_ies.data);
714 return SUCCESS;
715}
716
717void
718handle_s1ap_message(void *msg)
719{
720 log_msg(LOG_INFO, "Inside handle_s1ap_message.\n");
721 /*convert message from network to host*/
722
723 /*Call handler for the procedure code. TBD: Tasks pool for handlers*/
724
725 int enb_fd = 0;
726 int msg_size = 0;
727 memcpy(&enb_fd, msg, sizeof(int));
728 memcpy(&msg_size, msg + sizeof(int), sizeof(int));
729 char *message = ((char *) msg) + 2*sizeof(int);
730 S1AP_PDU_t pdu = {(S1AP_PDU_PR_NOTHING)};
731 S1AP_PDU_t *pdu_p = &pdu;
732 asn_dec_rval_t dec_ret = {(RC_OK)};
733 memset ((void *)pdu_p, 0, sizeof (S1AP_PDU_t));
734 dec_ret = aper_decode (NULL, &asn_DEF_S1AP_PDU, (void **)&pdu_p, message, msg_size, 0, 0);
735
736 if (dec_ret.code != RC_OK) {
737 log_msg(LOG_ERROR, "ASN Decode PDU Failed %d\n", dec_ret.consumed);
738 free(msg);
739 return;
740 }
741
742 switch (pdu_p->present) {
743 case S1AP_PDU_PR_initiatingMessage:
744 s1ap_mme_decode_initiating (pdu_p->choice.initiatingMessage, enb_fd);
745 break;
746 case S1AP_PDU_PR_successfulOutcome:
747 s1ap_mme_decode_successfull_outcome (pdu_p->choice.successfulOutcome);
748 break;
749 case S1AP_PDU_PR_unsuccessfulOutcome:
750 s1ap_mme_decode_unsuccessfull_outcome (pdu_p->choice.unsuccessfulOutcome);
751 break;
752 default:
753 log_msg(LOG_WARNING, "Unknown message outcome (%d) or not implemented", (int)pdu_p->present);
754 break;
755 }
756
757 return;
758}
759
760int
761s1ap_mme_decode_successfull_outcome (SuccessfulOutcome_t* msg)
762{
763 log_msg(LOG_DEBUG,"successful outcome decode :");
764 log_msg(LOG_INFO, "proc code %d\n", msg->procedureCode);
765 switch (msg->procedureCode) {
766
767 case S1AP_INITIAL_CTX_RESP_CODE:
768 s1_init_ctx_resp_handler(msg);
769 break;
770
771 case S1AP_UE_CONTEXT_RELEASE_CODE:
772 s1_ctx_release_complete_handler(msg);
773 break;
774
775 default:
776 log_msg(LOG_ERROR, "Unknown procedure code - %d\n",
777 msg->procedureCode & 0x00FF);
778 break;
779 }
780
781 return 0;
782}
783
784int
785s1ap_mme_decode_unsuccessfull_outcome (UnsuccessfulOutcome_t *msg)
786{
787 log_msg(LOG_DEBUG,"unsuccessful outcome decode : TBD");
788 return 0;
789}
790
791int
792s1ap_mme_decode_initiating (InitiatingMessage_t *initiating_p, int enb_fd)
793{
794 log_msg(LOG_INFO, "proc code %d\n", initiating_p->procedureCode);
795 switch (initiating_p->procedureCode) {
796
797 case S1AP_SETUP_REQUEST_CODE:
798 s1_setup_handler(initiating_p, enb_fd);
799 break;
800
801 case S1AP_INITIAL_UE_MSG_CODE:
802 init_ue_msg_handler(initiating_p, enb_fd);
803 break;
804
805 case S1AP_UL_NAS_TX_MSG_CODE:
806 UL_NAS_msg_handler(initiating_p, enb_fd);
807 break;
808
809 /*case S1AP_UE_CTX_RELEASE_CODE:
810 s1_ctx_release_resp_handler(initiating_p);
811 break;*/
812
813 case S1AP_UE_CONTEXT_RELEASE_REQUEST:
814 s1_ctx_release_request_handler(initiating_p);
815 break;
816
817 default:
818 log_msg(LOG_ERROR, "Unknown procedure code - %d\n",
819 initiating_p->procedureCode & 0x00FF);
820 break;
821 }
822
823 //free(msg);
824 return 0;
825}
826
827int convertUplinkNasToProtoIe(InitiatingMessage_t *msg, struct proto_IE* proto_ies)
828{
829 proto_ies->procedureCode = msg->procedureCode;
830 proto_ies->criticality = msg->criticality;
831 int no_of_IEs = 0;
832
833 if(msg->value.present == InitiatingMessage__value_PR_UplinkNASTransport)
834 {
835 ProtocolIE_Container_129P33_t* protocolIes = &msg->value.choice.UplinkNASTransport.protocolIEs;
836 no_of_IEs = protocolIes->list.count;
837 proto_ies->no_of_IEs = no_of_IEs;
838
839 log_msg(LOG_INFO, "No of IEs = %d\n", no_of_IEs);
840 proto_ies->data = calloc(sizeof(struct proto_IE_data), no_of_IEs);
841 if(proto_ies->data == NULL)
842 {
843 log_msg(LOG_ERROR,"Malloc failed for protocol IE.");
844 return -1;
845 }
846 for (int i = 0; i < protocolIes->list.count; i++) {
847 UplinkNASTransport_IEs_t *ie_p;
848 ie_p = protocolIes->list.array[i];
849 switch(ie_p->id) {
850 case ProtocolIE_ID_id_eNB_UE_S1AP_ID:
851 {
852 ENB_UE_S1AP_ID_t *s1apENBUES1APID_p = NULL;
853 if(UplinkNASTransport_IEs__value_PR_ENB_UE_S1AP_ID == ie_p->value.present)
854 {
855 s1apENBUES1APID_p = &ie_p->value.choice.ENB_UE_S1AP_ID;
856 }
857
858 if (s1apENBUES1APID_p == NULL) {
859 log_msg (LOG_ERROR, "Decoding of IE eNB_UE_S1AP_ID failed\n");
860 return -1;
861 }
862
863 proto_ies->data[i].IE_type = S1AP_IE_ENB_UE_ID;
864 memcpy(&proto_ies->data[i].val.enb_ue_s1ap_id, s1apENBUES1APID_p, sizeof(ENB_UE_S1AP_ID_t));
865 s1apENBUES1APID_p = NULL;
866 } break;
867 case ProtocolIE_ID_id_MME_UE_S1AP_ID:
868 {
869 MME_UE_S1AP_ID_t *s1apMMEUES1APID_p = NULL;
870 if(UplinkNASTransport_IEs__value_PR_MME_UE_S1AP_ID == ie_p->value.present)
871 {
872 s1apMMEUES1APID_p = &ie_p->value.choice.MME_UE_S1AP_ID;
873 }
874
875 if (s1apMMEUES1APID_p == NULL) {
876 log_msg (LOG_ERROR, "Decoding of IE MME_UE_S1AP_ID failed\n");
877 return -1;
878 }
879
880 proto_ies->data[i].IE_type = S1AP_IE_MME_UE_ID;
881 memcpy(&proto_ies->data[i].val.mme_ue_s1ap_id, s1apMMEUES1APID_p, sizeof(MME_UE_S1AP_ID_t));
882 s1apMMEUES1APID_p = NULL;
883 } break;
884 case ProtocolIE_ID_id_NAS_PDU:
885 {
886 NAS_PDU_t *s1apNASPDU_p = NULL;
887 if(UplinkNASTransport_IEs__value_PR_NAS_PDU == ie_p->value.present)
888 {
889 s1apNASPDU_p = &ie_p->value.choice.NAS_PDU;
890 }
891
892 if (s1apNASPDU_p == NULL) {
893 log_msg (LOG_ERROR, "Decoding of IE NAS PDU failed\n");
894 return -1;
895 }
896
897 proto_ies->data[i].IE_type = S1AP_IE_NAS_PDU;
898 parse_nas_pdu((char*)s1apNASPDU_p->buf, s1apNASPDU_p->size,
899 &proto_ies->data[i].val.nas, msg->procedureCode);
900 s1apNASPDU_p = NULL;
901 } break;
902 case ProtocolIE_ID_id_TAI:
903 {
904 TAI_t *s1apTAI_p = NULL;
905 if(UplinkNASTransport_IEs__value_PR_TAI == ie_p->value.present)
906 {
907 s1apTAI_p = &ie_p->value.choice.TAI;
908 }
909
910 if (s1apTAI_p == NULL) {
911 log_msg (LOG_ERROR, "Decoding of IE TAI failed\n");
912 return -1;
913 }
914
915 proto_ies->data[i].IE_type = S1AP_IE_TAI;
916 memcpy(&proto_ies->data[i].val.tai.tac, s1apTAI_p->tAC.buf, s1apTAI_p->tAC.size);
917 memcpy(&proto_ies->data[i].val.tai.plmn_id,
918 s1apTAI_p->pLMNidentity.buf, s1apTAI_p->pLMNidentity.size);
919 s1apTAI_p = NULL;
920 } break;
921 case ProtocolIE_ID_id_EUTRAN_CGI:
922 {
923 EUTRAN_CGI_t* s1apCGI_p = NULL;;
924 if(UplinkNASTransport_IEs__value_PR_EUTRAN_CGI == ie_p->value.present)
925 {
926 s1apCGI_p = &ie_p->value.choice.EUTRAN_CGI;
927 }
928
929 if (s1apCGI_p == NULL) {
930 log_msg (LOG_ERROR, "Decoding of IE CGI failed\n");
931 return -1;
932 }
933
934 proto_ies->data[i].IE_type = S1AP_IE_UTRAN_CGI;
935 memcpy(&proto_ies->data[i].val.utran_cgi.cell_id,
936 s1apCGI_p->cell_ID.buf, s1apCGI_p->cell_ID.size);
937 memcpy(&proto_ies->data[i].val.utran_cgi.plmn_id.idx,
938 s1apCGI_p->pLMNidentity.buf, s1apCGI_p->pLMNidentity.size);
939 s1apCGI_p = NULL;
940 } break;
941 default:
942 {
943 log_msg(LOG_WARNING, "Unhandled IE %d", ie_p->id);
944 }
945 }
946 }
947 }
948
949 return 0;
950}
951
952int convertInitCtxRspToProtoIe(SuccessfulOutcome_t *msg, struct proto_IE* proto_ies)
953{
954 proto_ies->procedureCode = msg->procedureCode;
955 proto_ies->criticality = msg->criticality;
956 int no_of_IEs = 0;
957
958 if(msg->value.present == SuccessfulOutcome__value_PR_InitialContextSetupResponse)
959 {
960 ProtocolIE_Container_129P20_t* protocolIes
961 = &msg->value.choice.InitialContextSetupResponse.protocolIEs;
962 no_of_IEs = protocolIes->list.count;
963 proto_ies->no_of_IEs = no_of_IEs;
964
965 log_msg(LOG_INFO, "No of IEs = %d\n", no_of_IEs);
966 proto_ies->data = calloc(sizeof(struct proto_IE_data), no_of_IEs);
967 if(proto_ies->data == NULL)
968 {
969 log_msg(LOG_ERROR,"Malloc failed for protocol IE.");
970 return -1;
971 }
972 for (int i = 0; i < protocolIes->list.count; i++) {
973 InitialContextSetupResponseIEs_t *ie_p;
974 ie_p = protocolIes->list.array[i];
975 switch(ie_p->id) {
976 case ProtocolIE_ID_id_eNB_UE_S1AP_ID:
977 {
978 ENB_UE_S1AP_ID_t *s1apENBUES1APID_p = NULL;
979 if(InitialContextSetupResponseIEs__value_PR_ENB_UE_S1AP_ID == ie_p->value.present)
980 {
981 s1apENBUES1APID_p = &ie_p->value.choice.ENB_UE_S1AP_ID;
982 }
983
984 if (s1apENBUES1APID_p == NULL) {
985 log_msg (LOG_ERROR, "Decoding of IE eNB_UE_S1AP_ID failed\n");
986 return -1;
987 }
988
989 proto_ies->data[i].IE_type = S1AP_IE_ENB_UE_ID;
990 memcpy(&proto_ies->data[i].val.enb_ue_s1ap_id, s1apENBUES1APID_p, sizeof(ENB_UE_S1AP_ID_t));
991 s1apENBUES1APID_p = NULL;
992 } break;
993 case ProtocolIE_ID_id_MME_UE_S1AP_ID:
994 {
995 MME_UE_S1AP_ID_t *s1apMMEUES1APID_p = NULL;
996 if(InitialContextSetupResponseIEs__value_PR_MME_UE_S1AP_ID == ie_p->value.present)
997 {
998 s1apMMEUES1APID_p = &ie_p->value.choice.MME_UE_S1AP_ID;
999 }
1000
1001 if (s1apMMEUES1APID_p == NULL) {
1002 log_msg (LOG_ERROR, "Decoding of IE MME_UE_S1AP_ID failed\n");
1003 return -1;
1004 }
1005
1006 proto_ies->data[i].IE_type = S1AP_IE_MME_UE_ID;
1007 memcpy(&proto_ies->data[i].val.mme_ue_s1ap_id, s1apMMEUES1APID_p, sizeof(MME_UE_S1AP_ID_t));
1008 s1apMMEUES1APID_p = NULL;
1009 } break;
1010 case ProtocolIE_ID_id_E_RABSetupListCtxtSURes:
1011 {
1012 E_RABSetupListCtxtSURes_t *s1apErabSetupList_p = NULL;
1013 if(InitialContextSetupResponseIEs__value_PR_E_RABSetupListCtxtSURes == ie_p->value.present)
1014 {
1015 s1apErabSetupList_p = &ie_p->value.choice.E_RABSetupListCtxtSURes;
1016 }
1017
1018 if (s1apErabSetupList_p == NULL) {
1019 log_msg (LOG_ERROR, "Decoding of IE s1apErabSetupList failed\n");
1020 return -1;
1021 }
1022
1023 proto_ies->data[i].IE_type = S1AP_ERAB_SETUP_CTX_SUR;
1024 proto_ies->data[i].val.erab.no_of_elements = s1apErabSetupList_p->list.count;
1025 proto_ies->data[i].val.erab.elements = calloc(sizeof(union eRAB_IE),
1026 s1apErabSetupList_p->list.count);
1027 if(proto_ies->data[i].val.erab.elements == NULL)
1028 {
1029 log_msg(LOG_ERROR,"Malloc failed for protocol IE: Erab elements.");
1030 break;;
1031 }
1032 for (int j = 0;
1033 j < s1apErabSetupList_p->list.count; j++)
1034 {
1035 E_RABSetupItemCtxtSUResIEs_t *ie_p;
1036 ie_p = (E_RABSetupItemCtxtSUResIEs_t*)s1apErabSetupList_p->list.array[j];
1037 switch(ie_p->id) {
1038 case ProtocolIE_ID_id_E_RABSetupItemCtxtSURes:
1039 {
1040 E_RABSetupItemCtxtSURes_t* s1apErabSetupItem_p = NULL;
1041 if(E_RABSetupItemCtxtSUResIEs__value_PR_E_RABSetupItemCtxtSURes == ie_p->value.present)
1042 {
1043 s1apErabSetupItem_p = &ie_p->value.choice.E_RABSetupItemCtxtSURes;
1044 }
1045
1046 if (s1apErabSetupItem_p == NULL) {
1047 log_msg (LOG_ERROR, "Decoding of IE s1apErabSetupItem failed\n");
1048 return -1;
1049 }
1050
1051 proto_ies->data[i].val.erab.elements[j].su_res.eRAB_id
1052 = (unsigned short)s1apErabSetupItem_p->e_RAB_ID;
1053 memcpy(
1054 &(proto_ies->data[i].val.erab.elements[j].su_res.gtp_teid),
1055 s1apErabSetupItem_p->gTP_TEID.buf,
1056 s1apErabSetupItem_p->gTP_TEID.size);
1057 proto_ies->data[i].val.erab.elements[j].su_res.gtp_teid
1058 = ntohl(proto_ies->data[i].val.erab.elements[j].su_res.gtp_teid);
1059
1060 memcpy(
1061 &(proto_ies->data[i].val.erab.elements[j].su_res.transp_layer_addr),
1062 s1apErabSetupItem_p->transportLayerAddress.buf,
1063 s1apErabSetupItem_p->transportLayerAddress.size);
1064 proto_ies->data[i].val.erab.elements[j].su_res.transp_layer_addr
1065 = ntohl(proto_ies->data[i].val.erab.elements[j].su_res.transp_layer_addr);
1066 s1apErabSetupItem_p = NULL;
1067 }break;
1068 default:
1069 {
1070 log_msg(LOG_WARNING, "Unhandled List item %d", ie_p->id);
1071 }
1072 }
1073 }
1074
1075 s1apErabSetupList_p = NULL;
1076 } break;
1077 default:
1078 {
1079 log_msg(LOG_WARNING, "Unhandled IE %d", ie_p->id);
1080 }
1081 }
1082 }
1083 }
1084
1085 return 0;
1086}
1087
1088int convertUeCtxRelComplToProtoIe(SuccessfulOutcome_t *msg, struct proto_IE* proto_ies)
1089{
1090 proto_ies->procedureCode = msg->procedureCode;
1091 proto_ies->criticality = msg->criticality;
1092 int no_of_IEs = 0;
1093
1094 if(msg->value.present == SuccessfulOutcome__value_PR_UEContextReleaseComplete)
1095 {
1096 ProtocolIE_Container_129P25_t* protocolIes
1097 = &msg->value.choice.UEContextReleaseComplete.protocolIEs;
1098 no_of_IEs = protocolIes->list.count;
1099 proto_ies->no_of_IEs = no_of_IEs;
1100
1101 log_msg(LOG_INFO, "No of IEs = %d\n", no_of_IEs);
1102 proto_ies->data = calloc(sizeof(struct proto_IE_data), no_of_IEs);
1103 if(proto_ies->data == NULL)
1104 {
1105 log_msg(LOG_ERROR,"Malloc failed for protocol IE.");
1106 return -1;
1107 }
1108 for (int i = 0; i < protocolIes->list.count; i++) {
1109 UEContextReleaseComplete_IEs_t *ie_p;
1110 ie_p = protocolIes->list.array[i];
1111 switch(ie_p->id) {
1112 case ProtocolIE_ID_id_eNB_UE_S1AP_ID:
1113 {
1114 ENB_UE_S1AP_ID_t *s1apENBUES1APID_p = NULL;
1115 if(UEContextReleaseComplete_IEs__value_PR_ENB_UE_S1AP_ID == ie_p->value.present)
1116 {
1117 s1apENBUES1APID_p = &ie_p->value.choice.ENB_UE_S1AP_ID;
1118 }
1119
1120 if (s1apENBUES1APID_p == NULL) {
1121 log_msg (LOG_ERROR, "Decoding of IE eNB_UE_S1AP_ID failed\n");
1122 return -1;
1123 }
1124
1125 proto_ies->data[i].IE_type = S1AP_IE_ENB_UE_ID;
1126 memcpy(&proto_ies->data[i].val.enb_ue_s1ap_id, s1apENBUES1APID_p, sizeof(ENB_UE_S1AP_ID_t));
1127 s1apENBUES1APID_p = NULL;
1128 } break;
1129 case ProtocolIE_ID_id_MME_UE_S1AP_ID:
1130 {
1131 MME_UE_S1AP_ID_t *s1apMMEUES1APID_p = NULL;
1132 if(UEContextReleaseComplete_IEs__value_PR_MME_UE_S1AP_ID == ie_p->value.present)
1133 {
1134 s1apMMEUES1APID_p = &ie_p->value.choice.MME_UE_S1AP_ID;
1135 }
1136
1137 if (s1apMMEUES1APID_p == NULL) {
1138 log_msg (LOG_ERROR, "Decoding of IE MME_UE_S1AP_ID failed\n");
1139 return -1;
1140 }
1141
1142 proto_ies->data[i].IE_type = S1AP_IE_MME_UE_ID;
1143 memcpy(&proto_ies->data[i].val.mme_ue_s1ap_id, s1apMMEUES1APID_p, sizeof(MME_UE_S1AP_ID_t));
1144 s1apMMEUES1APID_p = NULL;
1145 } break;
1146 default:
1147 {
1148 log_msg(LOG_WARNING, "Unhandled IE %d\n", ie_p->id);
1149 }
1150 }
1151 }
1152 }
1153
1154 return 0;
1155}
1156
1157int convertUeCtxRelReqToProtoIe(InitiatingMessage_t *msg, struct proto_IE* proto_ies)
1158{
1159 proto_ies->procedureCode = msg->procedureCode;
1160 proto_ies->criticality = msg->criticality;
1161 int no_of_IEs = 0;
1162
1163 if(msg->value.present == InitiatingMessage__value_PR_UEContextReleaseRequest)
1164 {
1165 ProtocolIE_Container_129P23_t* protocolIes
1166 = &msg->value.choice.UEContextReleaseRequest.protocolIEs;
1167 no_of_IEs = protocolIes->list.count;
1168 proto_ies->no_of_IEs = no_of_IEs;
1169
1170 log_msg(LOG_INFO, "No of IEs = %d\n", no_of_IEs);
1171 proto_ies->data = calloc(sizeof(struct proto_IE_data), no_of_IEs);
1172 if(proto_ies->data == NULL)
1173 {
1174 log_msg(LOG_ERROR,"Malloc failed for protocol IE.");
1175 return -1;
1176 }
1177 for (int i = 0; i < protocolIes->list.count; i++) {
1178 UEContextReleaseRequest_IEs_t *ie_p;
1179 ie_p = protocolIes->list.array[i];
1180 switch(ie_p->id) {
1181 case ProtocolIE_ID_id_eNB_UE_S1AP_ID:
1182 {
1183 ENB_UE_S1AP_ID_t *s1apENBUES1APID_p = NULL;
1184 if(UEContextReleaseRequest_IEs__value_PR_ENB_UE_S1AP_ID == ie_p->value.present)
1185 {
1186 s1apENBUES1APID_p = &ie_p->value.choice.ENB_UE_S1AP_ID;
1187 }
1188
1189 if (s1apENBUES1APID_p == NULL) {
1190 log_msg (LOG_ERROR, "Decoding of IE eNB_UE_S1AP_ID failed\n");
1191 return -1;
1192 }
1193
1194 proto_ies->data[i].IE_type = S1AP_IE_ENB_UE_ID;
1195 memcpy(&proto_ies->data[i].val.enb_ue_s1ap_id, s1apENBUES1APID_p, sizeof(ENB_UE_S1AP_ID_t));
1196 s1apENBUES1APID_p = NULL;
1197 } break;
1198 case ProtocolIE_ID_id_MME_UE_S1AP_ID:
1199 {
1200 MME_UE_S1AP_ID_t *s1apMMEUES1APID_p = NULL;
1201 if(UEContextReleaseRequest_IEs__value_PR_MME_UE_S1AP_ID == ie_p->value.present)
1202 {
1203 s1apMMEUES1APID_p = &ie_p->value.choice.MME_UE_S1AP_ID;
1204 }
1205
1206 if (s1apMMEUES1APID_p == NULL) {
1207 log_msg (LOG_ERROR, "Decoding of IE MME_UE_S1AP_ID failed\n");
1208 return -1;
1209 }
1210
1211 proto_ies->data[i].IE_type = S1AP_IE_MME_UE_ID;
1212 memcpy(&proto_ies->data[i].val.mme_ue_s1ap_id, s1apMMEUES1APID_p, sizeof(MME_UE_S1AP_ID_t));
1213 s1apMMEUES1APID_p = NULL;
1214 } break;
1215 case ProtocolIE_ID_id_Cause:
1216 {
1217 Cause_t *s1apCause_p = NULL;
1218 if(UEContextReleaseRequest_IEs__value_PR_Cause == ie_p->value.present)
1219 {
1220 s1apCause_p = &ie_p->value.choice.Cause;
1221 }
1222
1223 if (s1apCause_p == NULL) {
1224 log_msg (LOG_ERROR, "Decoding of IE Cause failed\n");
1225 return -1;
1226 }
1227
1228 proto_ies->data[i].IE_type = S1AP_IE_CAUSE;
1229 proto_ies->data[i].val.cause.present = s1apCause_p->present;
1230 switch(s1apCause_p->present)
1231 {
1232 case Cause_PR_radioNetwork:
1233 log_msg (LOG_DEBUG, "RadioNetwork case : %d\n",
1234 s1apCause_p->choice.radioNetwork);
1235 proto_ies->data[i].val.cause.choice.radioNetwork
1236 = s1apCause_p->choice.radioNetwork;
1237 break;
1238 case Cause_PR_transport:
1239 log_msg (LOG_DEBUG, "Transport case : %d\n",
1240 s1apCause_p->choice.transport);
1241 proto_ies->data[i].val.cause.choice.transport
1242 = s1apCause_p->choice.transport;
1243 break;
1244 case Cause_PR_nas:
1245 log_msg (LOG_DEBUG, "Nas case : %d\n",
1246 s1apCause_p->choice.nas);
1247 proto_ies->data[i].val.cause.choice.nas
1248 = s1apCause_p->choice.nas;
1249 break;
1250 case Cause_PR_protocol:
1251 log_msg (LOG_DEBUG, "Protocol case : %d\n",
1252 s1apCause_p->choice.protocol);
1253 proto_ies->data[i].val.cause.choice.protocol
1254 = s1apCause_p->choice.protocol;
1255 break;
1256 case Cause_PR_misc:
1257 log_msg (LOG_DEBUG, "Misc case : %d\n",
1258 s1apCause_p->choice.misc);
1259 proto_ies->data[i].val.cause.choice.misc
1260 = s1apCause_p->choice.misc;
1261 break;
1262 case Cause_PR_NOTHING:
1263 default:
1264 log_msg(LOG_WARNING, "Unknown cause %d\n", s1apCause_p->present);
1265
1266 }
1267 s1apCause_p = NULL;
1268 } break;
1269 default:
1270 {
1271 log_msg(LOG_WARNING, "Unhandled IE %d\n", ie_p->id);
1272 }
1273 }
1274 }
1275 }
1276
1277 return 0;
1278}
1279