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;
+}