MME2 changes - Propped commits from openmme/paging branch. Added scripts
for code gen

Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/src/s11/handlers/s11_msg_delegator.c b/src/s11/handlers/s11_msg_delegator.c
new file mode 100644
index 0000000..fbb0d7b
--- /dev/null
+++ b/src/s11/handlers/s11_msg_delegator.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd.
+ * Copyright (c) 2017 Intel Corporation
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "err_codes.h"
+#include "options.h"
+#include "ipc_api.h"
+#include "message_queues.h"
+#include "s11.h"
+#include "s11_config.h"
+#include "s11_structs.h"
+#include "../../gtpV2Codec/gtpV2StackWrappers.h"
+
+extern struct GtpV2Stack* gtpStack_gp;
+int s11_CS_resp_handler(MsgBuffer* message, GtpV2MessageHeader* hdr);
+int s11_MB_resp_handler(MsgBuffer* message, GtpV2MessageHeader* hdr);
+int s11_DS_resp_handler(MsgBuffer* message, GtpV2MessageHeader* hdr);
+int s11_RB_resp_handler(MsgBuffer* message, GtpV2MessageHeader* hdr);
+int s11_DDN_handler(MsgBuffer* message, GtpV2MessageHeader* hdr);
+
+/*
+  Get count of no of IEs in gtpv2c msg
+*/
+static int
+get_IE_cnt(char *msg, int len)
+{
+	int cnt = 0;
+	char *tmp = msg+11;
+	struct s11_IE_header *header = (struct s11_IE_header *)tmp;
+
+	for(; (char *)tmp <= msg + len; ++cnt) {
+		tmp += sizeof(struct s11_IE_header) + ntohs(header->ie_len);
+		header = (struct s11_IE_header*)tmp;
+	}
+	return cnt;
+}
+
+void
+network_cp_fteid(struct fteid *teid, char *data)
+{
+	unsigned int *tmp;
+
+	memcpy(teid, data, sizeof(struct fteid));
+	teid->header.teid_gre = ntohl(teid->header.teid_gre);
+	tmp = (unsigned int*)(data+5);
+	*tmp = ntohl(*tmp);
+	memcpy(&(teid->ip.ipv4), tmp, sizeof(struct in_addr));  
+}
+
+int
+parse_bearer_ctx(struct bearer_ctx *bearer, char* data, short len)
+{
+	char no_of_ies = 4;
+	//TODO: count no of IEs
+
+	for(int i=0; i < no_of_ies; ++i) {
+		struct s11_IE_header *header = (struct s11_IE_header*)data;
+		char *value = data + sizeof(struct s11_IE_header);
+
+		switch(header->ie_type){
+		case S11_IE_CAUSE:
+			memcpy(&(bearer->cause), value, sizeof(struct gtp_cause));
+			break;
+
+		case S11_IE_FTEID_C:{
+			#define S1U_SGW_FTEID 1 /*binary 0001*/
+			if((0x0F & (unsigned char)(*value)) 
+				== S1U_SGW_FTEID) {
+				network_cp_fteid(&bearer->s1u_sgw_teid, value);
+			}
+			else { /*s5s8 pgw_U ftied*/
+				network_cp_fteid(&bearer->s5s8_pgw_u_teid, value);
+			}
+			break;
+		}
+
+		case S11_IE_EPS_BEARER_ID:
+			bearer->eps_bearer_id = (unsigned char)(*value);
+			break;
+
+		default:
+		log_msg(LOG_ERROR, "Unhandled S11 bearer IE: %d\n", header->ie_type);
+		}
+
+		data += ntohs(header->ie_len) + sizeof(struct s11_IE_header); /*goto next IE*/
+	}
+	return SUCCESS;
+}
+
+int	
+parse_gtpv2c_IEs(char *msg, int len, struct s11_proto_IE *proto_ies)
+{
+	proto_ies->no_of_ies = get_IE_cnt(msg, len);
+
+	if(0 == proto_ies->no_of_ies) {
+		log_msg(LOG_INFO, "No IEs recvd in message\n");
+		return SUCCESS;
+	}
+	log_msg(LOG_INFO, "No of IEs - %d\n", proto_ies->no_of_ies);
+
+	/*allocated IEs for message*/
+	proto_ies->s11_ies = (struct s11_IE*)calloc(sizeof(struct s11_IE),
+				proto_ies->no_of_ies);
+	msg +=11;
+
+	for(int i=0; i < proto_ies->no_of_ies; ++i) {
+		struct s11_IE *ie = &(proto_ies->s11_ies[i]);
+		char *data = msg + sizeof(struct s11_IE_header);
+
+		memcpy(&(ie->header), msg, sizeof(struct s11_IE_header));
+
+		switch(ie->header.ie_type){
+		case S11_IE_CAUSE:
+			memcpy(&(ie->data.cause), data, sizeof(struct gtp_cause));
+			break;
+
+		case S11_IE_FTEID_C:{
+			#define S11_SGW_C_FTEID 11 /*binary 1011*/
+			if((0x0F & (unsigned char)(*data)) 
+				== S11_SGW_C_FTEID) {
+				network_cp_fteid(&(ie->data.s11_sgw_fteid), data);
+			}
+			else { /*s5s8 pgw_c ftied*/
+				network_cp_fteid(&(ie->data.s5s8_pgw_c_fteid), data);
+			}
+			break;
+		}
+
+		case S11_IE_PAA: {
+			memcpy(&(ie->data.pdn_addr.pdn_type), data,
+				sizeof(ie->data.pdn_addr.pdn_type));
+			memcpy(&(ie->data.pdn_addr.ip_type.ipv4), data+1, sizeof(int));
+			break;
+		}
+
+		case S11_IE_APN_RESTRICTION:
+			break;
+
+		case S11_IE_BEARER_CTX:
+			parse_bearer_ctx(&(ie->data.bearer), data, ntohs(ie->header.ie_len));
+		break;
+
+		default:
+		log_msg(LOG_ERROR, "Unhandled S11 IE: %d\n", ie->header.ie_type);
+		}
+
+		msg += (ntohs(((struct s11_IE_header*)msg)->ie_len) + sizeof(struct s11_IE_header)) ; /*goto next IE*/
+	}
+	return SUCCESS;
+}
+
+void
+handle_s11_message(void *message)
+{
+	log_msg(LOG_INFO, "S11 recv msg handler.\n");
+
+	MsgBuffer* msgBuf_p = (MsgBuffer*)(message);
+	
+	GtpV2MessageHeader msgHeader;
+
+	bool rc = GtpV2Stack_decodeMessageHeader(gtpStack_gp, &msgHeader, msgBuf_p);
+
+	switch(msgHeader.msgType){
+	case S11_GTP_CREATE_SESSION_RESP:
+		s11_CS_resp_handler(msgBuf_p, &msgHeader);
+		break;
+
+	case S11_GTP_MODIFY_BEARER_RESP:
+		s11_MB_resp_handler(msgBuf_p, &msgHeader);
+		break;
+
+	case S11_GTP_DELETE_SESSION_RESP:
+		s11_DS_resp_handler(msgBuf_p, &msgHeader);
+		break;
+	
+	case S11_GTP_RELEASE_BEARER_RESP:
+		s11_RB_resp_handler(msgBuf_p, &msgHeader);
+		break;
+	
+	case S11_GTP_DDN:
+                s11_DDN_handler(msgBuf_p, &msgHeader);
+                break;
+
+	}
+	return;
+}