Merge remote-tracking branch 'origin/develop' into merging-2019-w51-to-develop-nr

This commit is contained in:
Raphael Defosseux
2020-01-10 15:35:54 +01:00
184 changed files with 34802 additions and 1434 deletions
+2
View File
@@ -38,5 +38,7 @@
#include "sgw_lite_messages_types.h"
#include "udp_messages_types.h"
#include "mme_app_messages_types.h"
#include "m2ap_messages_types.h"
#endif /* MESSAGES_TYPES_H_ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+732
View File
@@ -0,0 +1,732 @@
import re, os, sys, string
import datetime
import getopt
import getpass
version = "1.0.2"
lines = ""
iesDefs = {}
ieofielist = {}
outdir = './'
filenames = []
verbosity = 0
prefix = ""
FAIL = '\033[91m'
WARN = '\033[93m'
ENDC = '\033[0m'
fileprefix = ""
fileprefix_first_upper = ""
def printFail(string):
sys.stderr.write(FAIL + string + ENDC + "\n")
def printWarning(string):
print WARN + string + ENDC
def printDebug(string):
if verbosity > 0:
print string
def outputHeaderToFile(f, filename):
now = datetime.datetime.now()
f.write("""/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
""")
f.write("/*******************************************************************************\n")
f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version))
f.write(" * Please do not modify this file but regenerate it via script.\n")
f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames))
f.write(" ******************************************************************************/\n")
def lowerFirstCamelWord(word):
""" puts the first word in a CamelCase Word in lowercase.
I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest
"""
newstr = ''
swapped = word.swapcase()
idx = 0
# if it's all-caps, return an all-lowered version
lowered = word.lower()
if swapped == lowered:
return lowered
for c in swapped:
if c in string.lowercase:
newstr += c
idx += 1
else:
break
if idx < 2:
newstr += word[idx:]
else:
newstr = newstr[:-1]+ word[idx-1:]
return newstr
def usage():
print "Python parser for asn1 v%s" % (version)
print "Usage: python asn1tostruct.py [options]"
print "Available options:"
print "-d Enable script debug"
print "-f [file] Input file to parse"
print "-o [dir] Output files to given directory"
print "-h Print this help and return"
try:
opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"])
except getopt.GetoptError as err:
# print help information and exit:
usage()
sys.exit(2)
for o, a in opts:
if o in ("-f", "--file"):
filenames.append(a)
if o in ("-d", "--debug"):
verbosity = 1
if o in ("-o", "--outdir"):
outdir = a
if outdir.rfind('/') != len(outdir):
outdir += '/'
if o in ("-h", "--help"):
usage()
sys.exit(2)
for filename in filenames:
file = open(filename, 'r')
for line in file:
# Removing any comment
if line.find('--') >= 0:
line = line[:line.find('--')]
# Removing any carriage return
lines += re.sub('\r', '', line)
for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE):
ieofielist[m[0]] = m[1]
for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE):
ieofielist[m[0]] = m[1]
for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n', lines, re.MULTILINE):
ies = []
maxLength = 0
# TODO: handle extensions
if i[1].find('EXTENSION') >= 0:
continue
if fileprefix == "":
fileprefix = i[1][:i[1].find('-')].lower()
for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE):
for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE):
printDebug("Got new ie for message " + i[0] + ": " + str(k))
if len(k[2]) > maxLength:
maxLength = len(k[2])
ies.append(k)
if len(ies) > 0:
iesDefs[i[0]] = { "length": maxLength, "ies": ies }
else:
printWarning("Didn't find any information element for message: " + i[0])
if len(iesDefs) == 0:
printFail("No Information Element parsed, exiting")
sys.exit(0)
fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:]
f = open(outdir + fileprefix + '_ies_defs.h', 'w')
outputHeaderToFile(f, filename)
f.write("#include \"%s_common.h\"\n\n" % (fileprefix))
f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper()))
f.write("/* Define the version of script used to generate this file */\n")
f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version)))
for key in iesDefs:
if key not in ieofielist.values():
continue
for (i, j) in ieofielist.items():
if j == key:
break
f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i)))
f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i])))))
f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i)))
for key in iesDefs:
keyupperunderscore = re.sub('-', '_', key.upper())
keylowerunderscore = re.sub('-', '_', key.lower())
shift = 0
if len(iesDefs[key]["ies"]) == 0:
continue
# Presence mask
for ie in iesDefs[key]["ies"]:
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
if ie[3] == "optional" or ie[3] == "conditional":
f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift,
pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9))
shift += 1
if (shift > 0):
f.write("\n")
f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key)))
if (shift > 0):
f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2))
for ie in iesDefs[key]["ies"]:
ieunderscore = re.sub('-', '_', ie[2])
iename = re.sub('id-', '', ie[0])
ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
if ie[2] in ieofielist:
f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore))
else:
f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2))
if ie[3] == "optional":
f.write(" ///< Optional field")
elif ie[3] == "conditional":
f.write(" ///< Conditional field")
f.write("\n")
f.write("} %s_t;\n\n" % (re.sub('-', '_', key)))
f.write("typedef struct %s_message_s {\n" % (fileprefix))
f.write(" %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper))
f.write(" %s_Criticality_t criticality;\n" % (fileprefix_first_upper))
f.write(" uint8_t direction;\n")
f.write(" union {\n")
messageList = iesDefs.keys()
messageList.sort()
for message in messageList:
if message in ieofielist.values():
continue
if len(iesDefs[message]["ies"]) == 0:
continue
f.write(" %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message))))
f.write(" } msg;\n")
f.write("} %s_message;\n\n" % (fileprefix))
for key in iesDefs:
if key in ieofielist.values():
continue
structName = re.sub('ies', '', key)
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
keylowerunderscore = re.sub('-', '_', key.lower())
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key))
f.write("/** \\brief Decode function for %s ies.\n" % (key))
if len(iesDefs[key]["ies"]) != 0:
f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
f.write(" **/\n")
f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore))
if len(iesDefs[key]["ies"]) != 0:
f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" ANY_t *any_p);\n\n")
if len(iesDefs[key]["ies"]) == 0:
continue
f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key))
f.write("/** \\brief Encode function for %s ies.\n" % (key))
f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" **/\n")
f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
for key in iesDefs:
if key not in ieofielist.values():
continue
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key))
f.write("/** \\brief Encode function for %s ies.\n" % (key))
f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" **/\n")
f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key))
f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower()))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower))
f.write("/** \\brief Decode function for %s ies.\n" % (key))
f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n")
f.write(" **/\n")
f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key))
f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
for key in iesDefs:
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
if key in ieofielist.values():
f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct))
f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" * \\param file File descriptor to write output.\n")
f.write(" **/\n")
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower())))
f.write(" asn_app_consume_bytes_f *cb,\n")
f.write(" void *app_key,\n")
f.write(" %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower))
else:
f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct))
f.write(" * \\param message_p Pointer to root message.\n")
f.write(" * \\param file File descriptor to write output.\n")
f.write(" **/\n")
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower()))
f.write(" asn_app_consume_bytes_f *cb,\n")
f.write(" void *app_key,\n")
f.write(" %s_message *message_p);\n\n" % (fileprefix))
f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower()))
f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
#Generate Decode functions
f = open(outdir + fileprefix + '_decoder.c', 'w')
outputHeaderToFile(f, filename)
f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
for key in iesDefs:
if key in ieofielist.values():
continue
structName = re.sub('ies', '', key)
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
asn1cStruct = asn1cStruct[:-1]
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
ielistname = re.sub('UE', 'ue', asn1cStruct)
ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
keyName = re.sub('-', '_', key)
keyupperunderscore = keyName.upper()
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
iesaccess = ""
if key not in ieofielist.values():
iesaccess = "%s_ies." % (firstlower)
f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
if len(iesDefs[key]["ies"]) != 0:
f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" ANY_t *any_p) {\n\n")
f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower))
f.write(" int i, decoded = 0;\n")
if len(iesDefs[key]["ies"]) != 0:
f.write(" int tempDecoded = 0;\n")
f.write(" assert(any_p != NULL);\n")
if len(iesDefs[key]["ies"]) != 0:
f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName)))
f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
f.write(" %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:]))
f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
f.write(" switch(ie_p->id) {\n")
for ie in iesDefs[key]["ies"]:
iename = re.sub('id-', '', ie[0])
ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
ietypesubst = re.sub('-', '', ie[2])
ietypeunderscore = re.sub('-', '_', ie[2])
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
if ie[3] == "optional":
f.write(" /* Optional field */\n")
elif ie[3] == "conditional":
f.write(" /* Conditional field */\n")
f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" {\n")
f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
if ie[3] != "mandatory":
f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst)))
f.write(" %s_ERROR(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
f.write(" if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst)))
f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" decoded += tempDecoded;\n")
f.write(" if (asn1_xer_print)\n")
f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
if ie[2] in ieofielist.keys():
f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" %s_ERROR(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" }\n")
else:
f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore))
#f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" } break;\n")
f.write(" default:\n")
f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" }\n")
f.write(" return decoded;\n")
f.write("}\n\n")
for key in iesDefs:
if key not in ieofielist.values():
continue
keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
f.write(" %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" int i, decoded = 0;\n")
f.write(" int tempDecoded = 0;\n\n")
f.write(" assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))));
f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))));
f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" switch (ie_p->id) {\n")
for ie in iesDefs[key]["ies"]:
iename = re.sub('id-', '', ie[0])
ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" {\n")
f.write(" %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" %s_ERROR(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname)))
f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
#f.write(" free(%s_p);\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" decoded += tempDecoded;\n")
f.write(" if (asn1_xer_print)\n")
f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" } break;\n")
f.write(" default:\n")
f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" }\n")
f.write(" return decoded;\n")
f.write("}\n\n")
#Generate IES Encode functions
f = open(outdir + fileprefix + '_encoder.c', 'w')
outputHeaderToFile(f,filename)
f.write("#include \"%s_common.h\"\n" % (fileprefix))
f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
for key in iesDefs:
if key in ieofielist.values():
continue
structName = re.sub('ies', '', key)
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
asn1cStruct = asn1cStruct[:-1]
asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
iesaccess = ""
if key not in ieofielist.values():
iesaccess = "%s_ies." % (firstwordlower)
keyName = re.sub('-', '_', key)
keyupperunderscore = keyName.upper()
# No IE to encode...
if len(iesDefs[key]["ies"]) == 0:
continue
f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
f.write(" assert(%s != NULL);\n" % (firstwordlower));
f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))));
for ie in iesDefs[key]["ies"]:
iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
ienameunderscore = re.sub('-', '_', iename)
ienamefirstwordlower = lowerFirstCamelWord(iename)
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
ietypeunderscore = re.sub('-', '_', ie[2])
if ie[3] != "mandatory":
if ie[3] == "optional":
f.write(" /* Optional field */\n")
elif ie[3] == "conditional":
f.write(" /* Conditional field */\n")
f.write(" if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
#f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
f.write(" }\n\n")
else:
if ie[2] in ieofielist.keys():
f.write(" %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower))
f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
f.write("\n")
f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
if ie[2] in ieofielist.keys():
f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower))
else:
f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
if ie[2] in ieofielist.keys():
f.write(" /* Free any dynamic allocation that is no more used */\n")
f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower))
f.write(" return 0;\n")
f.write("}\n\n")
for (key, value) in iesDefs.items():
if key not in ieofielist.values():
continue
ie = value["ies"][0]
ietypeunderscore = re.sub('-', '_', ie[2])
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
for (i, j) in ieofielist.items():
if j == key:
break
f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
f.write(" %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
f.write(" int i;\n")
f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
f.write(" assert(%s != NULL);\n" % (firstwordlower));
f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i))));
f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
f.write(" }\n")
f.write(" return 0;\n")
f.write("}\n\n")
#Generate xer print functions
f = open(outdir + fileprefix + '_xer_print.c', 'w')
outputHeaderToFile(f, filename)
f.write("#include <stdlib.h>\n")
f.write("#include <stdio.h>\n\n")
f.write("#include <asn_application.h>\n#include <asn_internal.h>\n\n")
f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower()))
f.write("""int
%s_xer__print2fp(const void *buffer, size_t size, void *app_key) {
FILE *stream = (FILE *)app_key;
if(fwrite(buffer, 1, size, stream) != size)
return -1;
return 0;
}
""" % (fileprefix.lower()))
f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) {
char *string = (char *)app_key;
/* Copy buffer to the formatted string */
memcpy(&string[%s_string_total_size], buffer, size);
%s_string_total_size += size;
return 0;
}
""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower()))
f.write("""static asn_enc_rval_t
xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr,
asn_app_consume_bytes_f *cb, void *app_key, int indent) {
asn_enc_rval_t er, tmper;
const char *mname;
size_t mlen;
int xcan = 2;
if(!td || !sptr) goto cb_failed;
mname = td->xml_tag;
mlen = strlen(mname);
ASN__TEXT_INDENT(0, indent);
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
tmper = td->op->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key);
if(tmper.encoded == -1) return tmper;
ASN__CALLBACK3("</", 2, mname, mlen, ">\\n", xcan);
er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
ASN__ENCODED_OK(er);
cb_failed:
ASN__ENCODE_FAILED;
}
""")
for (key, value) in iesDefs.items():
keyName = re.sub('-', '_', key)
keyupperunderscore = keyName.upper()
iesStructName = lowerFirstCamelWord(re.sub('-', '_', key))
ie = value["ies"][0]
ietypeunderscore = re.sub('-', '_', ie[2])
if key in ieofielist.values():
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower()))))
else:
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower())))
#f.write(" FILE *file,\n")
f.write(" asn_app_consume_bytes_f *cb,\n")
f.write(" void *app_key,\n")
if key in ieofielist.values():
iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key)))
f.write(" %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName))
f.write(" int i;\n")
f.write(" asn_enc_rval_t er;\n")
else:
f.write(" %s_message *message_p)\n{\n" % (fileprefix))
f.write(" %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName))
f.write(" asn_enc_rval_t er;\n")
#f.write(" void *app_key = (void *)file;\n")
#f.write(" asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower()))
f.write(" %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName))
if key in ieofielist.values():
# Increase indentation level
f.write(" for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
#f.write(" xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" }\n")
else:
f.write(" cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key))))
f.write(" xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper)
f.write(" xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper)
f.write(" cb(\" <%s>\\n\", %d, app_key);\n" % (key, len(" <%s>\n" % (key))))
for ie in iesDefs[key]["ies"]:
iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
ienameunderscore = re.sub('-', '_', iename)
ienamefirstwordlower = lowerFirstCamelWord(iename)
ietypeunderscore = re.sub('-', '_', ie[2])
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
if ie[3] != "mandatory":
if ie[3] == "optional":
f.write(" /* Optional field */\n")
elif ie[3] == "conditional":
f.write(" /* Conditional field */\n")
f.write(" if (%s->presenceMask & %s_%s_PRESENT)\n " % (iesStructName, keyupperunderscore, ieupperunderscore))
# Is it an encapsulated IE ?
if ie[2] in ieofielist.keys():
f.write(" %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower))
else:
f.write(" xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower))
f.write(" cb(\" </%s>\\n\", %d, app_key);\n" % (key, len(" </%s>\n" % (key))))
f.write(" cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key))))
f.write(" ASN__ENCODED_OK(er);\n")
#if key not in ieofielist.values():
#f.write("cb_failed:\n")
#f.write(" return er;\n")
f.write("}\n\n")
#Generate xer print functions
f = open(outdir + fileprefix + '_compare.c', 'w')
outputHeaderToFile(f, filename)
f.write("#include <stdlib.h>\n")
f.write("#include <stdio.h>\n\n")
f.write("#include <asn_application.h>\n#include <asn_internal.h>\n\n")
f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n" % (fileprefix, fileprefix))
f.write("#include \"%s-ProtocolIE-ID.h\"\n\n" % (fileprefix_first_upper))
for (key, value) in iesDefs.items():
if key not in ieofielist.values():
continue
ie = value["ies"][0]
ietypeunderscore = re.sub('-', '_', ie[2])
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
for (i, j) in ieofielist.items():
if j == key:
break
f.write("extern asn_TYPE_descriptor_t asn_DEF_%s;\n" % (ietypeunderscore))
+689
View File
@@ -0,0 +1,689 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE.c
* \brief m3ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "intertask_interface.h"
#include "m3ap_MCE.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_MCE_management_procedures.h"
#include "m3ap_MCE_handler.h"
//#include "m3ap_MCE_generate_messages.h"
#include "m3ap_common.h"
#include "m3ap_MCE_interface_management.h"
#include "m3ap_ids.h"
#include "m3ap_timers.h"
#include "queue.h"
#include "assertions.h"
#include "conversions.h"
struct m3ap_mce_map;
struct m3ap_MCE_data_s;
m3ap_setup_req_t * m3ap_mce_data_g;
RB_PROTOTYPE(m3ap_mce_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id);
static
void m3ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
static
void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
static
void m3ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
static
void m3ap_MCE_handle_register_MCE(instance_t instance,
m3ap_register_mce_req_t *m3ap_register_MME);
static
void m3ap_MCE_register_MCE(m3ap_MCE_instance_t *instance_p,
net_ip_address_t *target_MME_ip_addr,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t mce_port_for_M3C,
int multi_sd);
//static
//void m3ap_eNB_handle_handover_req(instance_t instance,
// m3ap_handover_req_t *m3ap_handover_req);
//
//static
//void m3ap_eNB_handle_handover_req_ack(instance_t instance,
// m3ap_handover_req_ack_t *m3ap_handover_req_ack);
//
//static
//void m3ap_eNB_ue_context_release(instance_t instance,
// m3ap_ue_context_release_t *m3ap_ue_context_release);
//
static
void m3ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
int result;
DevAssert(sctp_data_ind != NULL);
m3ap_MCE_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
static
void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
m3ap_MCE_instance_t *instance_p;
m3ap_MCE_data_t *m3ap_mce_data_p;
DevAssert(sctp_new_association_resp != NULL);
//printf("m3ap_eNB_handle_sctp_association_resp at 1\n");
//dump_trees();
instance_p = m3ap_MCE_get_instance(instance);
DevAssert(instance_p != NULL);
/* if the assoc_id is already known, it is certainly because an IND was received
* before. In this case, just update streams and return
*/
if (sctp_new_association_resp->assoc_id != -1) {
m3ap_mce_data_p = m3ap_get_MCE(instance_p, sctp_new_association_resp->assoc_id,
sctp_new_association_resp->ulp_cnx_id);
if (m3ap_mce_data_p != NULL) {
/* some sanity check - to be refined at some point */
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
M3AP_ERROR("m3ap_mce_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
abort();
}
m3ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams;
m3ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams;
return;
}
}
m3ap_mce_data_p = m3ap_get_MCE(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
DevAssert(m3ap_mce_data_p != NULL);
//printf("m3ap_MCE_handle_sctp_association_resp at 2\n");
//dump_trees_m3();
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
//m3ap_handle_m3_setup_message(instance_p, m3ap_enb_data_p,
//sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return;
}
//printf("m3ap_MCE_handle_sctp_association_resp at 3\n");
//dump_trees_m3();
/* Update parameters */
m3ap_mce_data_p->assoc_id = sctp_new_association_resp->assoc_id;
m3ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams;
m3ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams;
//printf("m3ap_MCE_handle_sctp_association_resp at 4\n");
//dump_trees_m3();
m3ap_mce_data_g->assoc_id = sctp_new_association_resp->assoc_id;
m3ap_mce_data_g->sctp_in_streams = sctp_new_association_resp->in_streams;
m3ap_mce_data_g->sctp_out_streams = sctp_new_association_resp->out_streams;
/* Prepare new m3 Setup Request */
//m3ap_eNB_generate_m3_setup_request(instance_p, m3ap_enb_data_p);
MCE_send_M3_SETUP_REQUEST(instance_p, m3ap_mce_data_p);
}
static
void m3ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
m3ap_MCE_instance_t *instance_p;
m3ap_MCE_data_t *m3ap_mce_data_p;
//printf("m3ap_MCE_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
//dump_trees_m3();
DevAssert(sctp_new_association_ind != NULL);
instance_p = m3ap_MCE_get_instance(instance);
DevAssert(instance_p != NULL);
m3ap_mce_data_p = m3ap_get_MCE(instance_p, sctp_new_association_ind->assoc_id, -1);
if (m3ap_mce_data_p != NULL) abort();
// DevAssert(m3ap_mce_data_p != NULL);
if (m3ap_mce_data_p == NULL) {
/* Create new MCE descriptor */
m3ap_mce_data_p = calloc(1, sizeof(*m3ap_mce_data_p));
DevAssert(m3ap_mce_data_p != NULL);
m3ap_mce_data_p->cnx_id = m3ap_MCE_fetch_add_global_cnx_id();
m3ap_mce_data_p->m3ap_MCE_instance = instance_p;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
RB_INSERT(m3ap_mce_map, &instance_p->m3ap_mce_head, m3ap_mce_data_p);
m3ap_mce_data_p->state = M3AP_MCE_STATE_CONNECTED;
instance_p->m3_target_mme_nb++;
if (instance_p->m3_target_mme_pending_nb > 0) {
instance_p->m3_target_mme_pending_nb--;
}
} else {
M3AP_WARN("m3ap_mce_data_p already exists\n");
}
//printf("m3ap_MCE_handle_sctp_association_ind at 2\n");
//dump_trees_m3();
/* Update parameters */
m3ap_mce_data_p->assoc_id = sctp_new_association_ind->assoc_id;
m3ap_mce_data_p->in_streams = sctp_new_association_ind->in_streams;
m3ap_mce_data_p->out_streams = sctp_new_association_ind->out_streams;
//printf("m3ap_MCE_handle_sctp_association_ind at 3\n");
//dump_trees_m3();
}
int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mce_port_for_M3C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M3AP_MCE, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = mce_port_for_M3C;
sctp_init->ppid = M3AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
static void m3ap_MCE_register_MCE(m3ap_MCE_instance_t *instance_p,
net_ip_address_t *target_MCE_ip_address,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t mce_port_for_M3C,
int multi_sd) {
MessageDef *message = NULL;
sctp_new_association_req_multi_t *sctp_new_association_req = NULL;
m3ap_MCE_data_t *m3ap_mce_data = NULL;
DevAssert(instance_p != NULL);
DevAssert(target_MCE_ip_address != NULL);
message = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI);
sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
sctp_new_association_req->port = mce_port_for_M3C;
sctp_new_association_req->ppid = M3AP_SCTP_PPID;
sctp_new_association_req->in_streams = in_streams;
sctp_new_association_req->out_streams = out_streams;
sctp_new_association_req->multi_sd = multi_sd;
memcpy(&sctp_new_association_req->remote_address,
target_MCE_ip_address,
sizeof(*target_MCE_ip_address));
memcpy(&sctp_new_association_req->local_address,
local_ip_addr,
sizeof(*local_ip_addr));
/* Create new MCE descriptor */
m3ap_mce_data = calloc(1, sizeof(*m3ap_mce_data));
DevAssert(m3ap_mce_data != NULL);
m3ap_mce_data->cnx_id = m3ap_MCE_fetch_add_global_cnx_id();
sctp_new_association_req->ulp_cnx_id = m3ap_mce_data->cnx_id;
m3ap_mce_data->assoc_id = -1;
m3ap_mce_data->m3ap_MCE_instance = instance_p;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
m3ap_mce_data_g = (m3ap_setup_req_t*)calloc(1,sizeof(m3ap_setup_req_t));
RB_INSERT(m3ap_mce_map, &instance_p->m3ap_mce_head, m3ap_mce_data);
m3ap_mce_data->state = M3AP_MCE_STATE_WAITING;
instance_p->m3_target_mme_nb ++;
instance_p->m3_target_mme_pending_nb ++;
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
}
static
void m3ap_MCE_handle_register_MCE(instance_t instance,
m3ap_register_mce_req_t *m3ap_register_MCE) {
m3ap_MCE_instance_t *new_instance;
DevAssert(m3ap_register_MCE != NULL);
/* Look if the provided instance already exists */
new_instance = m3ap_MCE_get_instance(instance);
if (new_instance != NULL) {
/* Checks if it is a retry on the same MCE */
DevCheck(new_instance->MCE_id == m3ap_register_MCE->MCE_id, new_instance->MCE_id, m3ap_register_MCE->MCE_id, 0);
DevCheck(new_instance->cell_type == m3ap_register_MCE->cell_type, new_instance->cell_type, m3ap_register_MCE->cell_type, 0);
DevCheck(new_instance->tac == m3ap_register_MCE->tac, new_instance->tac, m3ap_register_MCE->tac, 0);
DevCheck(new_instance->mcc == m3ap_register_MCE->mcc, new_instance->mcc, m3ap_register_MCE->mcc, 0);
DevCheck(new_instance->mnc == m3ap_register_MCE->mnc, new_instance->mnc, m3ap_register_MCE->mnc, 0);
M3AP_WARN("MCE[%d] already registered\n", instance);
} else {
new_instance = calloc(1, sizeof(m3ap_MCE_instance_t));
DevAssert(new_instance != NULL);
RB_INIT(&new_instance->m3ap_mce_head);
/* Copy usefull parameters */
new_instance->instance = instance;
new_instance->MCE_name = m3ap_register_MCE->MCE_name;
new_instance->MCE_id = m3ap_register_MCE->MCE_id;
new_instance->cell_type = m3ap_register_MCE->cell_type;
new_instance->tac = m3ap_register_MCE->tac;
new_instance->mcc = m3ap_register_MCE->mcc;
new_instance->mnc = m3ap_register_MCE->mnc;
new_instance->mnc_digit_length = m3ap_register_MCE->mnc_digit_length;
new_instance->num_cc = m3ap_register_MCE->num_cc;
m3ap_id_manager_init(&new_instance->id_manager);
m3ap_timers_init(&new_instance->timers,
m3ap_register_MCE->t_reloc_prep,
m3ap_register_MCE->tm3_reloc_overall);
for (int i = 0; i< m3ap_register_MCE->num_cc; i++) {
new_instance->eutra_band[i] = m3ap_register_MCE->eutra_band[i];
new_instance->downlink_frequency[i] = m3ap_register_MCE->downlink_frequency[i];
new_instance->uplink_frequency_offset[i] = m3ap_register_MCE->uplink_frequency_offset[i];
new_instance->Nid_cell[i] = m3ap_register_MCE->Nid_cell[i];
new_instance->N_RB_DL[i] = m3ap_register_MCE->N_RB_DL[i];
new_instance->frame_type[i] = m3ap_register_MCE->frame_type[i];
new_instance->fdd_earfcn_DL[i] = m3ap_register_MCE->fdd_earfcn_DL[i];
new_instance->fdd_earfcn_UL[i] = m3ap_register_MCE->fdd_earfcn_UL[i];
}
DevCheck(m3ap_register_MCE->nb_m3 <= M3AP_MAX_NB_MCE_IP_ADDRESS,
M3AP_MAX_NB_MCE_IP_ADDRESS, m3ap_register_MCE->nb_m3, 0);
memcpy(new_instance->target_mme_m3_ip_address,
m3ap_register_MCE->target_mme_m3_ip_address,
m3ap_register_MCE->nb_m3 * sizeof(net_ip_address_t));
new_instance->nb_m3 = m3ap_register_MCE->nb_m3;
new_instance->mme_m3_ip_address = m3ap_register_MCE->mme_m3_ip_address;
new_instance->sctp_in_streams = m3ap_register_MCE->sctp_in_streams;
new_instance->sctp_out_streams = m3ap_register_MCE->sctp_out_streams;
new_instance->mce_port_for_M3C = m3ap_register_MCE->mme_port_for_M3C;
/* Add the new instance to the list of MCE (meaningfull in virtual mode) */
m3ap_MCE_insert_new_instance(new_instance);
M3AP_INFO("Registered new MCE[%d] and %s MCE id %u\n",
instance,
m3ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home",
m3ap_register_MCE->MCE_id);
printf("ipv4_address %s\n",m3ap_register_MCE->mme_m3_ip_address.ipv4_address);
/* initiate the SCTP listener */
if (m3ap_MCE_init_sctp(new_instance,&m3ap_register_MCE->mme_m3_ip_address,m3ap_register_MCE->mme_port_for_M3C) < 0 ) {
M3AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
return;
}
M3AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n",
instance, m3ap_register_MCE->MCE_id);
}
}
static
void m3ap_MCE_handle_sctp_init_msg_multi_cnf(
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m) {
m3ap_MCE_instance_t *instance;
int index;
DevAssert(m != NULL);
instance = m3ap_MCE_get_instance(instance_id);
DevAssert(instance != NULL);
instance->multi_sd = m->multi_sd;
/* Exit if CNF message reports failure.
* Failure means multi_sd < 0.
*/
if (instance->multi_sd < 0) {
M3AP_ERROR("Error: be sure to properly configure M3 in your configuration file.\n");
DevAssert(instance->multi_sd >= 0);
}
/* Trying to connect to the provided list of MCE ip address */
for (index = 0; index < instance->nb_m3; index++) {
M3AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n",
instance_id, instance->MCE_id);
m3ap_MCE_register_MCE(instance,
&instance->target_mme_m3_ip_address[index],
&instance->mme_m3_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->mce_port_for_M3C,
instance->multi_sd);
}
}
//static
//void m3ap_eNB_handle_handover_req(instance_t instance,
// m3ap_handover_req_t *m3ap_handover_req)
//{
// m3ap_eNB_instance_t *instance_p;
// m3ap_eNB_data_t *target;
// m3ap_id_manager *id_manager;
// int ue_id;
//
// int target_pci = m3ap_handover_req->target_physCellId;
//
// instance_p = m3ap_eNB_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m3ap_is_eNB_pci_in_list(target_pci);
// DevAssert(target != NULL);
//
// /* allocate m3ap ID */
// id_manager = &instance_p->id_manager;
// ue_id = m3ap_allocate_new_id(id_manager);
// if (ue_id == -1) {
// M3AP_ERROR("could not allocate a new M3AP UE ID\n");
// /* TODO: cancel handover: send (to be defined) message to RRC */
// exit(1);
// }
// /* id_source is ue_id, id_target is unknown yet */
// m3ap_set_ids(id_manager, ue_id, m3ap_handover_req->rnti, ue_id, -1);
// m3ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE);
// m3ap_set_reloc_prep_timer(id_manager, ue_id,
// m3ap_timer_get_tti(&instance_p->timers));
// m3ap_id_set_target(id_manager, ue_id, target);
//
// m3ap_eNB_generate_m3_handover_request(instance_p, target, m3ap_handover_req, ue_id);
//}
//static
//void m3ap_eNB_handle_handover_req_ack(instance_t instance,
// m3ap_handover_req_ack_t *m3ap_handover_req_ack)
//{
// /* TODO: remove this hack (the goal is to find the correct
// * eNodeB structure for the other end) - we need a proper way for RRC
// * and M3AP to identify eNodeBs
// * RRC knows about mod_id and M3AP knows about eNB_id (eNB_ID in
// * the configuration file)
// * as far as I understand.. CROUX
// */
// m3ap_eNB_instance_t *instance_p;
// m3ap_eNB_data_t *target;
// int source_assoc_id = m3ap_handover_req_ack->source_assoc_id;
// int ue_id;
// int id_source;
// int id_target;
//
// instance_p = m3ap_eNB_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m3ap_get_eNB(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// /* rnti is a new information, save it */
// ue_id = m3ap_handover_req_ack->m3_id_target;
// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
// m3ap_set_ids(&instance_p->id_manager, ue_id, m3ap_handover_req_ack->rnti, id_source, id_target);
//
// m3ap_eNB_generate_m3_handover_request_ack(instance_p, target, m3ap_handover_req_ack);
//}
//
//static
//void m3ap_eNB_ue_context_release(instance_t instance,
// m3ap_ue_context_release_t *m3ap_ue_context_release)
//{
// m3ap_eNB_instance_t *instance_p;
// m3ap_eNB_data_t *target;
// int source_assoc_id = m3ap_ue_context_release->source_assoc_id;
// int ue_id;
// instance_p = m3ap_eNB_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m3ap_get_eNB(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// m3ap_eNB_generate_m3_ue_context_release(instance_p, target, m3ap_ue_context_release);
//
// /* free the M3AP UE ID */
// ue_id = m3ap_find_id_from_rnti(&instance_p->id_manager, m3ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M3AP_ERROR("could not find UE %x\n", m3ap_ue_context_release->rnti);
// exit(1);
// }
// m3ap_release_id(&instance_p->id_manager, ue_id);
//}
uint8_t m3ap_m3setup[] = {
0x00, 0x07, 0x00, 0x23, 0x00, 0x00, 0x03, 0x00,
0x12, 0x00, 0x07, 0x40, 0x55, 0xf5, 0x01, 0x00,
0x25, 0x00, 0x00, 0x13, 0x40, 0x0a, 0x03, 0x80,
0x4d, 0x33, 0x2d, 0x65, 0x4e, 0x42, 0x33, 0x37,
0x00, 0x14, 0x00, 0x03, 0x01, 0x00, 0x01
};
uint8_t m3ap_start[] = {
0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00,
0x07, 0x00, 0x55, 0xf5, 0x01, 0x00, 0x00, 0x01,
0x00, 0x04, 0x00, 0x0d, 0x60, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x01,
0x7a, 0x00, 0x05, 0x00, 0x03, 0x07, 0x08, 0x00,
0x00, 0x06, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00,
0x0e, 0x00, 0xe8, 0x0a, 0x0a, 0x0a, 0x00, 0x0a,
0xc8, 0x0a, 0xfe, 0x00, 0x00, 0x00, 0x01
};
void *m3ap_MCE_task(void *arg) {
MessageDef *received_msg = NULL;
int result;
M3AP_DEBUG("Starting M3AP MCE layer\n");
m3ap_MCE_prepare_internal_data();
itti_mark_task_ready(TASK_M3AP_MCE);
while (1) {
itti_receive_msg(TASK_M3AP_MCE, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case MESSAGE_TEST:
// LOG_W(M3AP,"MCE Received Test Message ... TODO\n");
// //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP, MESSAGE_TEST);
// //itti_send_msg_to_task(TASK_M2AP_ENB, 1/*ctxt_pP->module_id*/, message_p);
//
// asn_dec_rval_t dec_ret;
//
//
// uint8_t *buffer;
// uint32_t len;
// M3AP_M3AP_PDU_t pdu;
// memset(&pdu, 0, sizeof(pdu));
//
// buffer = &m3ap_m3setup[0];
// //buffer = &m3ap_start[0];
// len=8*4+7;
// //len=8*9+7;
//
// //if (m3ap_decode_pdu(&pdu, buffer, len) < 0) {
// // LOG_E(M3AP, "Failed to decode PDU\n");
// //re//turn -1;
// //}
// M3AP_M3AP_PDU_t *pdu2 = &pdu;
// dec_ret = aper_decode(NULL,
// &asn_DEF_M3AP_M3AP_PDU,
// (void **)&pdu2,
// buffer,
// len,
// 0,
// 0);
//
// LOG_W(M3AP,"Trying to print %d\n",(dec_ret.code == RC_OK));
// xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, &pdu);
// LOG_W(M3AP,"Trying to print out \n");
break;
case TERMINATE_MESSAGE:
M3AP_WARN(" *** Exiting M3AP thread\n");
itti_exit_task();
break;
case M3AP_SUBFRAME_PROCESS:
m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
break;
case M3AP_REGISTER_MCE_REQ:
LOG_I(M3AP,"MCE Received M3AP_REGISTER_MCE_REQ Message\n");
m3ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_REGISTER_MCE_REQ(received_msg));
break;
case M3AP_MBMS_SESSION_START_RESP:
LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_START_RESP Message\n");
MCE_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_MBMS_SESSION_START_RESP(received_msg));
break;
case M3AP_MBMS_SESSION_STOP_RESP:
LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_STOP_RESP Message\n");
MCE_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_MBMS_SESSION_START_RESP(received_msg));
break;
case M3AP_MBMS_SESSION_UPDATE_RESP:
LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_UPDATE_RESP Message\n");
//MCE_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
//&M3AP_MBMS_SESSION_START_RESP(received_msg));
break;
// case M3AP_HANDOVER_REQ:
// m3ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_HANDOVER_REQ(received_msg));
// break;
//
// case M3AP_HANDOVER_REQ_ACK:
// m3ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_HANDOVER_REQ_ACK(received_msg));
// break;
//
// case M3AP_UE_CONTEXT_RELEASE:
// m3ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_UE_CONTEXT_RELEASE(received_msg));
// break;
//
case SCTP_INIT_MSG_MULTI_CNF:
LOG_D(M3AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n");
m3ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_NEW_ASSOCIATION_RESP:
LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n");
m3ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
break;
case SCTP_NEW_ASSOCIATION_IND:
LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n");
m3ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_ind);
break;
case SCTP_DATA_IND:
LOG_D(M3AP,"MCE Received SCTP_DATA_IND Message\n");
m3ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_data_ind);
break;
default:
M3AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
}
return NULL;
}
#include "common/config/config_userapi.h"
int is_m3ap_MCE_enabled(void)
{
static volatile int config_loaded = 0;
static volatile int enabled = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if (pthread_mutex_lock(&mutex)) goto mutex_error;
if (config_loaded) {
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
}
char *enable_m3 = NULL;
paramdef_t p[] = {
{ "enable_mce_m3", "yes/no", 0, strptr:&enable_m3, defstrval:"", TYPE_STRING, 0 }
};
/* TODO: do it per module - we check only first MCE */
config_get(p, sizeof(p)/sizeof(paramdef_t), "MCEs.[0]");
if (enable_m3 != NULL && strcmp(enable_m3, "yes") == 0)
enabled = 1;
config_loaded = 1;
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
mutex_error:
LOG_E(M3AP, "mutex error\n");
exit(1);
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB.h
* \brief m3ap tasks for eNB
* \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M3AP_MCE_H_
#define M3AP_MCE_H_
#include "m3ap_MCE_defs.h"
int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mce_port_for_M3C);
void *m3ap_MCE_task(void *arg);
int is_m3ap_MCE_enabled(void);
#endif /* M3AP_H_ */
/**
* @}
*/
+210
View File
@@ -0,0 +1,210 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_defs.h
* \brief m3ap struct definitions for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "m3ap_ids.h" //looks X2AP specific for HO
#include "m3ap_timers.h"
#ifndef M3AP_MCE_DEFS_H_
#define M3AP_MCE_DEFS_H_
#define M3AP_MCE_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M3AP_MCE_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target MCE accepts or
* M3 Setup failure if rejects the MCE.
*/
M3AP_MCE_STATE_WAITING = 0x1,
/* The MCE is successfully connected to another MCE. */
M3AP_MCE_STATE_CONNECTED = 0x2,
/* M3AP is ready, and the MCE is successfully connected to another MCE. */
M3AP_MCE_STATE_READY = 0x3,
M3AP_MCE_STATE_OVERLOAD = 0x4,
M3AP_MCE_STATE_RESETTING = 0x5,
/* Max number of states available */
M3AP_MCE_STATE_MAX,
} m3ap_MCE_state_t;
/* Served PLMN identity element */
/*struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};*/
/* Served group id element */
/*struct served_group_id_s {
uint16_t mce_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};*/
/* Served enn code for a particular MCE */
/*struct mce_code_s {
uint8_t mce_code;
STAILQ_ENTRY(mce_code_s) next;
};*/
struct m3ap_MCE_instance_s;
/* This structure describes association of a MCE to another MCE */
typedef struct m3ap_MCE_data_s {
/* MCE descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m3ap_MCE_data_s) entry;
/* This is the optional name provided by the MME */
char *MCE_name;
/* target MCE ID */
uint32_t MCE_id;
/* Current MCE load information (if any). */
//m3ap_load_state_t overload_state;
/* Current MCE->MCE M3AP association state */
m3ap_MCE_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/M3AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/* Only meaningfull in virtual mode */
struct m3ap_MCE_instance_s *m3ap_MCE_instance;
} m3ap_MCE_data_t;
typedef struct m3ap_MCE_instance_s {
/* used in simulation to store multiple MCE instances*/
STAILQ_ENTRY(m3ap_MCE_instance_s) m3ap_MCE_entries;
/* Number of target MCEs requested by MCE (tree size) */
uint32_t m3_target_mme_nb;
/* Number of target MCEs for which association is pending */
uint32_t m3_target_mme_pending_nb;
/* Number of target MCE successfully associated to MCE */
uint32_t m3_target_mme_associated_nb;
/* Tree of M3AP MCE associations ordered by association ID */
RB_HEAD(m3ap_mce_map, m3ap_MCE_data_s) m3ap_mce_head;
/* Tree of UE ordered by MCE_ue_m3ap_id's */
// RB_HEAD(m3ap_ue_map, m3ap_MCE_ue_context_s) m3ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of MCE */
char *MCE_name;
/* Unique MCE_id to identify the MCE within EPC.
* In our case the MCE is a macro MCE so the id will be 20 bits long.
* For Home MCE id, this field should be 28 bits long.
*/
uint32_t MCE_id;
/* The type of the cell */
cell_type_t cell_type;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* CC params */
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MCE_IP_ADDRESS];
uint8_t nb_m3;
net_ip_address_t mme_m3_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t mce_port_for_M3C;
int multi_sd;
m3ap_id_manager id_manager;
m3ap_timers_t timers;
} m3ap_MCE_instance_t;
typedef struct {
/* List of served MCEs
* Only used for virtual mode
*/
STAILQ_HEAD(m3ap_MCE_instances_head_s, m3ap_MCE_instance_s) m3ap_MCE_instances_head;
/* Nb of registered MCEs */
uint8_t nb_registered_MCEs;
/* Generate a unique connexion id used between M3AP and SCTP */
uint16_t global_cnx_id;
} m3ap_MCE_internal_data_t;
int m3ap_MCE_compare_assoc_id(struct m3ap_MCE_data_s *p1, struct m3ap_MCE_data_s *p2);
/* Generate the tree management functions */
struct m3ap_MCE_map;
struct m3ap_MCE_data_s;
RB_PROTOTYPE(m3ap_MCE_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id);
#endif /* M3AP_MCE_DEFS_H_ */
@@ -0,0 +1,63 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_eNB_generate_messages.h
* \brief m2ap procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_ENB_GENERATE_MESSAGES_H_
#define M2AP_ENB_GENERATE_MESSAGES_H_
#include "m2ap_eNB_defs.h"
#include "m2ap_common.h"
int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p,
m2ap_eNB_data_t *m2ap_eNB_data_p);
int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p);
/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait);*/
int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value);
//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id);
//
//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause);
#endif /* M2AP_ENB_GENERATE_MESSAGES_H_ */
+808
View File
@@ -0,0 +1,808 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_eNB_generate_messages.c
* \brief m2ap procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include "intertask_interface.h"
//#include "M2AP_LastVisitedCell-Item.h"
#include "m2ap_common.h"
#include "m2ap_eNB.h"
#include "m2ap_eNB_generate_messages.h"
#include "m2ap_encoder.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
#include "m2ap_itti_messaging.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
int m2ap_eNB_generate_m2_setup_request(
m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p)
{
module_id_t enb_mod_idP=0;
module_id_t du_mod_idP=0;
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupRequest_t *out;
M2AP_M2SetupRequest_Ies_t *ie;
uint8_t *buffer;
uint32_t len;
int i = 0;
int j = 0;
/* Create */
/* 0. pdu Type */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
//pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
/* mandatory */
/* c1. GlobalENB_ID (integer value) */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
ie->criticality = M2AP_Criticality_reject;
ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID;
//ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
&ie->value.choice.GlobalENB_ID.pLMN_Identity);
ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
&ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
///* mandatory */
///* c2. GNB_eNB_ID (integrer value) */
//ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_gNB_eNB_ID;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID;
//asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id);
//ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* optional */
/* c3. ENBname */
if (m2ap_eNB_data_p->eNB_name != NULL) {
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
ie->id = M2AP_ProtocolIE_ID_id_ENBname;
ie->criticality = M2AP_Criticality_ignore;
ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENBname;
//OCTET_STRING_fromBuf(&ie->value.choice.ENB_Name, m2ap_eNB_data_p->eNB_name,
//strlen(m2ap_eNB_data_p->eNB_name));
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
}
/* mandatory */
/* c4. serverd cells list */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List;
ie->criticality = M2AP_Criticality_reject;
ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List;
int num_mbms_available = 1;//m2ap_du_data->num_mbms_available;
LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available);
for (i=0;
i<num_mbms_available;
i++) {
/* mandatory */
/* 4.1 serverd cells item */
M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *mbms_configuration_data_list_item_ies;
mbms_configuration_data_list_item_ies = (M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *)calloc(1, sizeof(M2AP_ENB_MBMS_Configuration_data_ItemIEs_t));
mbms_configuration_data_list_item_ies->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item;
mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject;
mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item;
M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item;
mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item;
{
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
&mbms_configuration_data_item->eCGI.pLMN_Identity);
MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
&mbms_configuration_data_item->eCGI.eUTRANcellIdentifier);
M2AP_MBMS_Service_Area_t * mbms_service_area;
mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
}
//M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item;
//memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t));
//M2AP_ECGI_t eCGI;
//M2AP_PLMN_Identity_t pLMN_Identity;
//M2AP_EUTRANCellIdentifier_t eUTRANcellIdentifier
//M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea;
//M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList;
ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
LOG_W(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id);
/* encode */
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(M2AP, "Failed to encode M2 setup request\n");
return -1;
}
LOG_W(M2AP,"pdu.present %d\n",pdu.present);
// MSC_LOG_TX_MESSAGE(
// MSC_M2AP_eNB,
// MSC_M2AP_MCE,
// (const char *)buffer,
// len,
// MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// m2ap_eNB_data_p->ENBname);
m2ap_eNB_itti_send_sctp_data_req(instance_p, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
return 0;
}
//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_M2SetupResponse_t *out;
// M2AP_M2SetupResponse_Ies_t *ie;
// //M2AP_PLMN_Identity_t *plmn;
// //ServedCells__Member *servedCellMember;
// //M2AP_GU_Group_ID_t *gu;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// /* Prepare the M2AP message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
// out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
//
// /* mandatory */
// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalENB_ID;
// //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// // &ie->value.choice.GlobalENB_ID.pLMN_Identity);
// //ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
// //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
// // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
// //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells;
// //{
// // for (int i = 0; i<instance_p->num_cc; i++){
// // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
// // {
// // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
//
// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// // &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
// // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
// // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
//
// // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
// // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
// // {
// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
// // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
// // }
//
// // if (instance_p->frame_type[i] == FDD) {
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
// // switch (instance_p->N_RB_DL[i]) {
// // case 6:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// // break;
// // case 15:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// // break;
// // case 25:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// // break;
// // case 50:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// // break;
// // case 75:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// // break;
// // case 100:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// // break;
// // default:
// // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
// // break;
// // }
// // }
// // else {
// // AssertFatal(0,"M2Setupresponse not supported for TDD!");
// // }
// // }
// // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
// // }
// //}
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList;
// //{
// // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
// // {
// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// // &gu->pLMN_Identity);
// // //@TODO: consider to update this value
// // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
// // }
// // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
// //}
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode M2 setup response\n");
// return -1;
// }
//
// m2ap_eNB_data_p->state = M2AP_ENB_STATE_READY;
//
// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
//
// return ret;
//}
//int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
// uint32_t assoc_id,
// M2AP_Cause_PR cause_type,
// long cause_value,
// long time_to_wait)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_M2SetupFailure_t *out;
// M2AP_M2SetupFailure_Ies_t *ie;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// /* Prepare the M2AP message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
// pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
// pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
// out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
//
// /* mandatory */
// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_Cause;
// //ie->criticality = M2AP_Criticality_ignore;
// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause;
//
// //m2ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional: consider to handle this later */
// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait;
// //ie->criticality = M2AP_Criticality_ignore;
// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait;
//
// //if (time_to_wait > -1) {
// // ie->value.choice.TimeToWait = time_to_wait;
// //}
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode M2 setup failure\n");
// return -1;
// }
//
// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB,
// // MSC_M2AP_TARGET_ENB, NULL, 0,
// // "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u",
// // assoc_id, cause_type, cause_value);
//
// m2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
//
// return ret;
//}
int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value)
{
DevAssert (cause_p != NULL);
cause_p->present = cause_type;
switch (cause_type) {
case M2AP_Cause_PR_radioNetwork:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_transport:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_protocol:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_misc:
cause_p->choice.misc = cause_value;
break;
default:
return -1;
}
return 0;
}
//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequest_t *out;
// M2AP_HandoverRequest_IEs_t *ie;
// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause;
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.ECGI.pLMN_Identity);
// MACRO_ENB_ID_TO_CELL_IDENTITY(m2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
// //@TODO: consider to update these values
// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
// //@TODO: consider to update this value
// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id;
//
// KENB_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
//
// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc;
// }
// else {
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
// }
//
// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
//
// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
//
// //@TODO: update with proper UEAMPR
// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
// {
// for (int i=0;i<m2ap_handover_req->nb_e_rabs_tobesetup;i++) {
// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t));
// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
// {
// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8);
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
// m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer,
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
// }
// }
//
// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
// //@TODO: consider to update this value
// {
// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t));
// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
// MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small;
// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover request\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequestAcknowledge_t *out;
// M2AP_HandoverRequestAcknowledge_IEs_t *ie;
// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs;
// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// ue_id = m2ap_handover_req_ack->m2_id_target;
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
//
// {
// for (int i=0;i<m2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t));
// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
// {
// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
// }
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer;
//
// OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover response\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_UEContextRelease_t *out;
// M2AP_UEContextRelease_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
// exit(1);
// }
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP ue context relase message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease;
// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 UE Context Release\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverCancel_t *out;
// M2AP_HandoverCancel_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// ue_id = m2_ue_id;
// id_source = ue_id;
// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id);
//
// /* Prepare the M2AP handover cancel message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional */
// if (id_target != -1) {
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// }
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause;
// switch (cause) {
// case M2AP_T_RELOC_PREP_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_trelocprep_expiry;
// break;
// case M2AP_TX2_RELOC_OVERALL_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_tx2relocoverall_expiry;
// break;
// default:
// /* we can't come here */
// M2AP_ERROR("unhandled cancel cause\n");
// exit(1);
// }
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 Handover Cancel\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
+118
View File
@@ -0,0 +1,118 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB_handler.c
* \brief m3ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m3ap_common.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_handler.h"
#include "m3ap_decoder.h"
#include "m3ap_ids.h"
//#include "m3ap_MCE_management_procedures.h"
#include "m3ap_MCE_generate_messages.h"
//#include "m3ap_MME_interface_management.h"
#include "m3ap_MCE_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m3ap_MCE_message_decoded_callback m3ap_MCE_messages_callback[][3] = {
{ MCE_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart */
{ MCE_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ 0, 0, 0 }, /* ??? */
{ MCE_handle_MBMS_SESSION_UPDATE_REQUEST, 0, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ 0, MCE_handle_M3_SETUP_RESPONSE, 0 } /* M3 Setup */
};
static char *m3ap_direction2String(int m3ap_dir) {
static char *m3ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m3ap_direction_String[m3ap_dir]);
}
int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M3AP_M3AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m3ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M3AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_MCE_messages_callback) / (3 * sizeof(
m3ap_message_decoded_callback))
|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m3ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M3AP, "Calling handler with instance %d\n",instance);
ret = (*m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return ret;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_handler.h
* \brief m2ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_HANDLERS_H_
#define M2AP_MCE_HANDLERS_H_
#include "m2ap_MCE_defs.h"
//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
//const uint8_t * const data, const uint32_t data_length);
int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
#endif /* M2AP_MCE_HANDLERS_H_ */
@@ -0,0 +1,756 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_interface_management.c
* \brief m3ap interface management for MCE
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#include "intertask_interface.h"
#include "m3ap_common.h"
#include "m3ap_MCE.h"
//#include "m3ap_MCE_generate_messages.h"
#include "m3ap_encoder.h"
#include "m3ap_decoder.h"
#include "m3ap_ids.h"
#include "m3ap_MCE_interface_management.h"
#include "m3ap_itti_messaging.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
//#include "m3ap_common.h"
//#include "m3ap_encoder.h"
//#include "m3ap_decoder.h"
//#include "m3ap_itti_messaging.h"
//#include "m3ap_MCE_interface_management.h"
//#include "assertions.h"
extern m3ap_setup_req_t * m3ap_mce_data_g;
int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu){
// LOG_W(M3AP, "MCE_handle_MBMS_SESSION_START_REQUEST assoc_id %d\n",assoc_id);
//
MessageDef *message_p;
// M3AP_SessionStartRequest_t *container;
// M3AP_SessionStartRequest_Ies_t *ie;
// int i = 0;
//
// DevAssert(pdu != NULL);
//
// container = &pdu->choice.initiatingMessage.value.choice.SessionStartRequest;
message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_START_REQ);
//
// /* M3 Setup Request == Non UE-related procedure -> stream 0 */
// if (stream != 0) {
// LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
// assoc_id, stream);
// }
//
itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
// if(1){
// MCE_send_MBMS_SESSION_START_RESPONSE(instance,assoc_id);
// }else
// MCE_send_MBMS_SESSION_START_FAILURE(instance,assoc_id);
return 0;
}
int MCE_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp){
//AssertFatal(1==0,"Not implemented yet\n");
// module_id_t mce_mod_idP;
// module_id_t enb_mod_idP;
//
// // This should be fixed
// enb_mod_idP = (module_id_t)0;
// mce_mod_idP = (module_id_t)0;
//
M3AP_M3AP_PDU_t pdu;
M3AP_MBMSSessionStartResponse_t *out;
M3AP_MBMSSessionStartResponse_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
//int i = 0;
/* Create */
/* 0. Message Type */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome;
//pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t));
pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_mBMSsessionStart;
pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_MBMSSessionStartResponse;
out = &pdu.choice.successfulOutcome.value.choice.MBMSSessionStartResponse;
/* mandatory */
/* c1. MCE_MBMS_M3AP_ID (integer value) */ //long
ie = (M3AP_MBMSSessionStartResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartResponse_IEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_MBMSSessionStartResponse_IEs__value_PR_MCE_MBMS_M3AP_ID;
//ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
/* c1. MME_MBMS_M3AP_ID (integer value) */ //long
ie = (M3AP_MBMSSessionStartResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartResponse_IEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_MBMSSessionStartResponse_IEs__value_PR_MME_MBMS_M3AP_ID;
//ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(M3AP, "Failed to encode M3 SessionStart Response\n");
return -1;
}
//
//
// LOG_W(M3AP,"pdu.present %d\n",pdu.present);
// // MSC_LOG_TX_MESSAGE(
// // MSC_M3AP_MCE,
// // MSC_M3AP_MCE,
// // (const char *)buffer,
// // len,
// // MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s",
// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// // m3ap_MCE_data_p->MCEname);
//
m3ap_MCE_itti_send_sctp_data_req(instance, m3ap_mce_data_g->assoc_id, buffer, len, 0);
return 0;
}
int MCE_send_MBMS_SESSION_START_FAILURE(instance_t instance, m3ap_session_start_failure_t * m3ap_session_start_failure){
// module_id_t enb_mod_idP;
// module_id_t mce_mod_idP;
//
// // This should be fixed
// enb_mod_idP = (module_id_t)0;
// mce_mod_idP = (module_id_t)0;
//
// M3AP_M3AP_PDU_t pdu;
// M3AP_SessionStartFailure_t *out;
// M3AP_SessionStartFailure_Ies_t *ie;
//
// uint8_t *buffer;
// uint32_t len;
//
// /* Create */
// /* 0. Message Type */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome;
// //pdu.choice.unsuccessfulOutcome = (M3AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M3AP_UnsuccessfulOutcome_t));
// pdu.choice.unsuccessfulOutcome.procedureCode = M3AP_ProcedureCode_id_sessionStart;
// pdu.choice.unsuccessfulOutcome.criticality = M3AP_Criticality_reject;
// pdu.choice.unsuccessfulOutcome.value.present = M3AP_UnsuccessfulOutcome__value_PR_SessionStartFailure;
// out = &pdu.choice.unsuccessfulOutcome.value.choice.SessionStartFailure;
//
// /* mandatory */
// /* c1. Transaction ID (integer value)*/
// // ie = (M3AP_M3SetupFailure_Ies_t *)calloc(1, sizeof(M3AP_M3SetupFailure_Ies_t));
// // ie->id = M3AP_ProtocolIE_ID_id_GlobalMCE_ID;
// // ie->criticality = M3AP_Criticality_reject;
// // ie->value.present = M3AP_M3SetupFailure_Ies__value_PR_GlobalMCE_ID;
// // ie->value.choice.GlobalMCE_ID = M3AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP);
// // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// /* c2. Cause */
// ie = (M3AP_M3SetupFailure_Ies_t *)calloc(1, sizeof(M3AP_SessionStartFailure_Ies_t));
// ie->id = M3AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M3AP_Criticality_ignore;
// ie->value.present = M3AP_SessionStartFailure_Ies__value_PR_Cause;
// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork = M3AP_CauseRadioNetwork_unspecified;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
//
// /* encode */
// if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) {
// LOG_E(M3AP, "Failed to encode M3 setup request\n");
// return -1;
// }
//
// //mce_m3ap_itti_send_sctp_data_req(instance, m3ap_mce_data_from_enb->assoc_id, buffer, len, 0);
// m3ap_MCE_itti_send_sctp_data_req(instance,assoc_id,buffer,len,0);
//
return 0;
}
int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu){
//AssertFatal(1==0,"Not implemented yet\n");
LOG_D(M3AP, "MCE_handle_MBMS_SESSION_STOP_REQUEST assoc_id %d\n",assoc_id);
MessageDef *message_p;
//M3AP_MBMSSessionStopRequest_t *container;
//M3AP_MBMSSessionStopRequest_IEs_t *ie;
//int i = 0;
DevAssert(pdu != NULL);
//container = &pdu->choice.initiatingMessage.value.choice.MBMSSessionStopRequest;
/* M3 Setup Request == Non UE-related procedure -> stream 0 */
if (stream != 0) {
LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
assoc_id, stream);
}
//if(1){
//MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id);
//}else
//MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id);
message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_STOP_REQ);
//
// /* M3 Setup Request == Non UE-related procedure -> stream 0 */
// if (stream != 0) {
// LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
// assoc_id, stream);
// }
//
itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
return 0;
}
int MCE_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp){
// module_id_t mce_mod_idP;
// module_id_t enb_mod_idP;
//
// // This should be fixed
// enb_mod_idP = (module_id_t)0;
// mce_mod_idP = (module_id_t)0;
//
M3AP_M3AP_PDU_t pdu;
M3AP_MBMSSessionStopResponse_t *out;
M3AP_MBMSSessionStopResponse_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
//int i = 0;
/* Create */
/* 0. Message Type */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome;
//pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t));
pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_mBMSsessionStop;
pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_MBMSSessionStopResponse;
out = &pdu.choice.successfulOutcome.value.choice.MBMSSessionStopResponse;
/* mandatory */
/* c1. MCE_MBMS_M3AP_ID (integer value) */ //long
ie = (M3AP_MBMSSessionStopResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStopResponse_IEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_MBMSSessionStopResponse_IEs__value_PR_MCE_MBMS_M3AP_ID;
//ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
/* c1. MCE_MBMS_M3AP_ID (integer value) */ //long
ie = (M3AP_MBMSSessionStopResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStopResponse_IEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_MBMSSessionStopResponse_IEs__value_PR_MCE_MBMS_M3AP_ID;
//ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(M3AP, "Failed to encode M3 SessionStop Response\n");
return -1;
}
LOG_D(M3AP,"pdu.present %d\n",pdu.present);
// MSC_LOG_TX_MESSAGE(
// MSC_M3AP_MCE,
// MSC_M3AP_MCE,
// (const char *)buffer,
// len,
// MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s",
// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// m3ap_MCE_data_p->MCEname);
m3ap_MCE_itti_send_sctp_data_req(instance, m3ap_mce_data_g->assoc_id, buffer, len, 0);
return 0;
}
/*
* Session Update
*/
int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu)
{
//AssertFatal(1==0,"Not implemented yet\n");
LOG_D(M3AP, "MCE_handle_MBMS_SESSION_UPDATE_REQUEST assoc_id %d\n",assoc_id);
MessageDef *message_p;
//M3AP_MBMSSessionUpdateRequest_t *container;
//M3AP_MBMSSessionUpdateRequest_IEs_t *ie;
//int i = 0;
DevAssert(pdu != NULL);
//container = &pdu->choice.initiatingMessage.value.choice.MBMSSessionUpdateRequest;
/* M3 Setup Request == Non UE-related procedure -> stream 0 */
if (stream != 0) {
LOG_D(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
assoc_id, stream);
}
//if(1){
//MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id);
//}else
//MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id);
message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_UPDATE_REQ);
//
// /* M3 Setup Request == Non UE-related procedure -> stream 0 */
// if (stream != 0) {
// LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
// assoc_id, stream);
// }
//
itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
return 0;
}
int MCE_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m3ap_mbms_session_update_resp_t * m3ap_mbms_session_update_resp){
M3AP_M3AP_PDU_t pdu;
M3AP_MBMSSessionUpdateResponse_t *out;
M3AP_MBMSSessionUpdateResponse_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
//int i = 0;
/* Create */
/* 0. Message Type */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome;
//pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t));
pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_mBMSsessionUpdate;
pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_MBMSSessionUpdateResponse;
out = &pdu.choice.successfulOutcome.value.choice.MBMSSessionUpdateResponse;
/* mandatory */
/* c1. MCE_MBMS_M3AP_ID (integer value) */ //long
ie = (M3AP_MBMSSessionUpdateResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateResponse_IEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_MBMSSessionUpdateResponse_IEs__value_PR_MCE_MBMS_M3AP_ID;
//ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
/* c1. MCE_MBMS_M3AP_ID (integer value) */ //long
ie = (M3AP_MBMSSessionUpdateResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateResponse_IEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_MBMSSessionUpdateResponse_IEs__value_PR_MCE_MBMS_M3AP_ID;
//ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(M3AP, "Failed to encode M3 SessionUpdate Response\n");
return -1;
}
LOG_D(M3AP,"pdu.present %d\n",pdu.present);
// MSC_LOG_TX_MESSAGE(
// MSC_M3AP_MCE,
// MSC_M3AP_MCE,
// (const char *)buffer,
// len,
// MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s",
// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// m3ap_MCE_data_p->MCEname);
m3ap_MCE_itti_send_sctp_data_req(instance, m3ap_mce_data_g->assoc_id, buffer, len, 0);
return 0;
}
int MCE_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m3ap_mbms_session_update_failure_t * m3ap_mbms_session_update_failure){
return 0;
}
/*
M3 Setup
*/
//uint8_t m3ap_m3setup_message[] = {0x00,0x07,0x00,0x23,0x00,0x00,0x03,0x00,0x12,0x00,0x07,0x40,0x55,0xf5,0x01,0x00,0x25,0x00,0x00,0x13,0x40,0x0a,0x03,0x80,0x4d,0x33,0x2d,0x65,0x4e,0x42,0x33,0x37,0x00,0x14,0x00,0x03,0x01,0x00,0x01};
uint8_t m3ap_m3setup_message[] = {
0x00, 0x07, 0x00, 0x23, 0x00, 0x00, 0x03, 0x00,
0x12, 0x00, 0x07, 0x40, 0x55, 0xf5, 0x01, 0x00,
0x25, 0x00, 0x00, 0x13, 0x40, 0x0a, 0x03, 0x80,
0x4d, 0x33, 0x2d, 0x65, 0x4e, 0x42, 0x33, 0x37,
0x00, 0x14, 0x00, 0x03, 0x01, 0x00, 0x01
};
//uint8_t m3ap_start_message[] = {
// 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x07, 0x00,
// 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00,
// 0x07, 0x00, 0x55, 0xf5, 0x01, 0x00, 0x00, 0x01,
// 0x00, 0x04, 0x00, 0x0d, 0x60, 0x01, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x01,
// 0x7a, 0x00, 0x05, 0x00, 0x03, 0x07, 0x08, 0x00,
// 0x00, 0x06, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00,
// 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00,
// 0x0e, 0x00, 0xe8, 0x0a, 0x0a, 0x0a, 0x00, 0x0a,
// 0xc8, 0x0a, 0xfe, 0x00, 0x00, 0x00, 0x01
//};
//
// SETUP REQUEST
int MCE_send_M3_SETUP_REQUEST(m3ap_MCE_instance_t *instance_p, m3ap_MCE_data_t *m3ap_MCE_data_p) {
// module_id_t enb_mod_idP=0;
// module_id_t du_mod_idP=0;
//
M3AP_M3AP_PDU_t pdu;
M3AP_M3SetupRequest_t *out;
M3AP_M3SetupRequestIEs_t *ie;
uint8_t *buffer;
uint32_t len;
//int i = 0;
//int j = 0;
/* Create */
/* 0. pdu Type */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage;
//pdu.choice.initiatingMessage = (M3AP_InitiatingMessage_t *)calloc(1, sizeof(M3AP_InitiatingMessage_t));
pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_m3Setup;
pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject;
pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_M3SetupRequest;
out = &pdu.choice.initiatingMessage.value.choice.M3SetupRequest;
/* mandatory */
/* c1. GlobalMCE_ID (integer value) */
ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t));
ie->id = M3AP_ProtocolIE_ID_id_Global_MCE_ID;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_M3SetupRequestIEs__value_PR_Global_MCE_ID;
//ie->value.choice.GlobalMCE_ID.MCE_ID = 1;//M3AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
&ie->value.choice.Global_MCE_ID.pLMN_Identity);
//ie->value.choice.Global_MCE_ID.MCE_ID.present = M3AP_MCE_ID_PR_macro_MCE_ID;
OCTET_STRING_fromBuf(&ie->value.choice.Global_MCE_ID.mCE_ID,"02",2);
// MACRO_ENB_ID_TO_BIT_STRING(instance_p->MCE_id,
// &ie->value.choice.Global_MCE_ID.mCE_ID);
//M3AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
// ie->value.choice.Global_MCE_ID.mCE_ID.buf[0],
// ie->value.choice.Global_MCE_ID.mCE_ID.buf[1],
// ie->value.choice.Global_MCE_ID.mCE_ID.buf[2]);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// ///* mandatory */
// ///* c2. GNB_MCE_ID (integrer value) */
// //ie = (M3AP_M3SetupRequest_Ies_t *)calloc(1, sizeof(M3AP_M3SetupRequest_Ies_t));
// //ie->id = M3AP_ProtocolIE_ID_id_gNB_MCE_ID;
// //ie->criticality = M3AP_Criticality_reject;
// //ie->value.present = M3AP_M3SetupRequestIEs__value_PR_GNB_MCE_ID;
// //asn_int642INTEGER(&ie->value.choice.GNB_MCE_ID, f1ap_du_data->gNB_MCE_id);
// //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional */
/* c3. MCEname */
//m3ap_MCE_data_p->MCE_name="kk";
if (m3ap_MCE_data_p->MCE_name != NULL) {
ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MCEname;
ie->criticality = M3AP_Criticality_ignore;
ie->value.present = M3AP_M3SetupRequestIEs__value_PR_MCEname;
OCTET_STRING_fromBuf(&ie->value.choice.MCEname, m3ap_MCE_data_p->MCE_name,
strlen(m3ap_MCE_data_p->MCE_name));
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
}
/* mandatory */ //but removed from asn definition (optional) since it crashes when decoding ???????????
// M3SetupRequestIEs M3AP-PROTOCOL-IES ::= {
// { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE mandatory}|
// { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}|
// { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE mandatory}, --> optional ??????????
// ...
// }
/* M3AP_MBMSServiceAreaListItem_t */
ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t));
ie->id = M3AP_ProtocolIE_ID_id_MBMSServiceAreaList;
ie->criticality = M3AP_Criticality_reject;
ie->value.present = M3AP_M3SetupRequestIEs__value_PR_MBMSServiceAreaListItem;
//M3AP_MBMSServiceAreaListItem_t * m3ap_mbmsservicearealistitem = (M3AP_MBMSServiceAreaListItem_t*)calloc(1,sizeof(M3AP_MBMSServiceAreaListItem_t));
M3AP_MBMSServiceArea1_t * m3ap_mbmsservicearea1 = (M3AP_MBMSServiceArea1_t*)calloc(1,sizeof(M3AP_MBMSServiceArea1_t));
OCTET_STRING_fromBuf(m3ap_mbmsservicearea1,"02",2);
//ASN_SEQUENCE_ADD(&m3ap_mbmsservicearealistitem->list,m3ap_mbmsservicearea1);
//ASN_SEQUENCE_ADD(&ie->value.choice.MBMSServiceAreaListItem,m3ap_mbmsservicearealistitem);
//ASN_SEQUENCE_ADD(&ie->value.choice.MBMSServiceAreaListItem.list,m3ap_mbmsservicearealistitem);
ASN_SEQUENCE_ADD(&ie->value.choice.MBMSServiceAreaListItem.list,m3ap_mbmsservicearea1);
//ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// /* c4. serverd cells list */
// ie = (M3AP_M3SetupRequest_Ies_t *)calloc(1, sizeof(M3AP_M3SetupRequest_Ies_t));
// ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_Configuration_data_List;
// ie->criticality = M3AP_Criticality_reject;
// ie->value.present = M3AP_M3SetupRequest_Ies__value_PR_MCE_MBMS_Configuration_data_List;
//
// int num_mbms_available = 1;//m3ap_du_data->num_mbms_available;
// LOG_D(M3AP, "num_mbms_available = %d \n", num_mbms_available);
//
// for (i=0;
// i<num_mbms_available;
// i++) {
// /* mandatory */
// /* 4.1 serverd cells item */
//
// M3AP_MCE_MBMS_Configuration_data_ItemIEs_t *mbms_configuration_data_list_item_ies;
// mbms_configuration_data_list_item_ies = (M3AP_MCE_MBMS_Configuration_data_ItemIEs_t *)calloc(1, sizeof(M3AP_MCE_MBMS_Configuration_data_ItemIEs_t));
// mbms_configuration_data_list_item_ies->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_Configuration_data_Item;
// mbms_configuration_data_list_item_ies->criticality = M3AP_Criticality_reject;
// mbms_configuration_data_list_item_ies->value.present = M3AP_MCE_MBMS_Configuration_data_ItemIEs__value_PR_MCE_MBMS_Configuration_data_Item;
//
// M3AP_MCE_MBMS_Configuration_data_Item_t *mbms_configuration_data_item;
// mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.MCE_MBMS_Configuration_data_Item;
// {
// /* M3AP_ECGI_t eCGI */
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &mbms_configuration_data_item->eCGI.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
// &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier);
// /* M3AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea */
// mbms_configuration_data_item->mbsfnSynchronisationArea=10000; //? long
// /* M3AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList */
// M3AP_MBMS_Service_Area_t * mbms_service_area,*mbms_service_area2;
// mbms_service_area = (M3AP_MBMS_Service_Area_t*)calloc(1,sizeof(M3AP_MBMS_Service_Area_t));
// mbms_service_area2 = (M3AP_MBMS_Service_Area_t*)calloc(1,sizeof(M3AP_MBMS_Service_Area_t));
// //memset(mbms_service_area,0,sizeof(OCTET_STRING_t));
// OCTET_STRING_fromBuf(mbms_service_area,"01",2);
// ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
// OCTET_STRING_fromBuf(mbms_service_area2,"02",2);
// ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area2);
//
//
// }
//
//
// //M3AP_MCE_MBMS_Configuration_data_Item_t mbms_configuration_data_item;
// //memset((void *)&mbms_configuration_data_item, 0, sizeof(M3AP_MCE_MBMS_Configuration_data_Item_t));
//
// //M3AP_ECGI_t eCGI;
// //M3AP_PLMN_Identity_t pLMN_Identity;
// //M3AP_EUTRANCellIdentifier_t eUTRANcellIdentifier
// //M3AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea;
// //M3AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList;
//
//
// ASN_SEQUENCE_ADD(&ie->value.choice.MCE_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies);
//
// }
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// LOG_W(M3AP,"m3ap_MCE_data_p->assoc_id %d\n",m3ap_MCE_data_p->assoc_id);
// /* encode */
// xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, &pdu);
// xer_fprint(stdout, &asn_DEF_M3AP_M3SetupRequest, &pdu.choice.initiatingMessage.value.choice.M3SetupRequest);
// xer_fprint(stdout, &asn_DEF_M3AP_M3SetupRequest, out);
if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(M3AP, "Failed to encode M3 setup request\n");
return -1;
}
/* buffer = &m3ap_start_message[0];
len=8*9+7;
buffer = &m3ap_m3setup_message[0];
len=8*4+7; */
//
//
// LOG_W(M3AP,"pdu.present %d\n",pdu.present);
// // MSC_LOG_TX_MESSAGE(
// // MSC_M3AP_MCE,
// // MSC_M3AP_MCE,
// // (const char *)buffer,
// // len,
// // MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s",
// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// // m3ap_MCE_data_p->MCEname);
//
//
//// buffer = &bytes[0];
//// len = 40;
////
//// for(int i=0; i < len; i++ )
//// printf("%02X",buffer[i]);
//// printf("\n");
////
// M3AP_M3AP_PDU_t pdu2;
//
// memset(&pdu2, 0, sizeof(pdu2));
//
// for( i=0; i < len; i++)
// printf("%02X",buffer[i]);
// printf("\n");
//
// if (m3ap_decode_pdu(&pdu2, buffer, len) < 0) {
// LOG_E(M3AP, "Failed to decode PDU\n");
// //return -1;
// }
//
//printf("m3ap_MCE_data_p->assoc_id %d\n",m3ap_MCE_data_p->assoc_id);
m3ap_MCE_itti_send_sctp_data_req(instance_p->instance, m3ap_MCE_data_p->assoc_id, buffer, len, 0);
return 0;
}
int MCE_handle_M3_SETUP_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu)
{
LOG_D(M3AP, "MCE_handle_M3_SETUP_RESPONSE\n");
AssertFatal(pdu->present == M3AP_M3AP_PDU_PR_successfulOutcome,
"pdu->present != M3AP_M3AP_PDU_PR_successfulOutcome\n");
AssertFatal(pdu->choice.successfulOutcome.procedureCode == M3AP_ProcedureCode_id_m3Setup,
"pdu->choice.successfulOutcome.procedureCode != M3AP_ProcedureCode_id_M3Setup\n");
AssertFatal(pdu->choice.successfulOutcome.criticality == M3AP_Criticality_reject,
"pdu->choice.successfulOutcome.criticality != M3AP_Criticality_reject\n");
AssertFatal(pdu->choice.successfulOutcome.value.present == M3AP_SuccessfulOutcome__value_PR_M3SetupResponse,
"pdu->choice.successfulOutcome.value.present != M3AP_SuccessfulOutcome__value_PR_M3SetupResponse\n");
//M3AP_M3SetupResponse_t *in = &pdu->choice.successfulOutcome.value.choice.M3SetupResponse;
//M3AP_M3SetupResponseIEs_t *ie;
//int GlobalMCE_ID = -1;
//int num_cells_to_activate = 0;
//M3AP_Cells_to_be_Activated_List_Item_t *cell;
MessageDef *msg_p = itti_alloc_new_message (TASK_M3AP_MCE, M3AP_SETUP_RESP);
// LOG_D(M3AP, "M3AP: M3Setup-Resp: protocolIEs.list.count %d\n",
// in->protocolIEs.list.count);
// for (int i=0;i < in->protocolIEs.list.count; i++) {
// ie = in->protocolIEs.list.array[i];
// }
//AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n");
//AssertFatal(num_cells_to_activate>0,"No cells activated\n");
//M3AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
//for (int i=0;i<num_cells_to_activate;i++)
// AssertFatal(M3AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
//MSC_LOG_RX_MESSAGE(
// MSC_M3AP_MCE,
// MSC_M3AP_CU,
// 0,
// 0,
// MSC_AS_TIME_FMT" MCE_handle_M3_SETUP_RESPONSE successfulOutcome assoc_id %d",
// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// assoc_id);
//LOG_D(M3AP, "Sending M3AP_SETUP_RESP ITTI message to MCE_APP with assoc_id (%d->%d)\n",
// assoc_id,MCE_MOMCELE_ID_TO_INSTANCE(assoc_id));
itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
return 0;
}
// SETUP FAILURE
int MCE_handle_M3_SETUP_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu) {
LOG_E(M3AP, "MCE_handle_M3_SETUP_FAILURE\n");
return 0;
}
@@ -0,0 +1,119 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_interface_management.h
* \brief m3ap interface management for MCE
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M3AP_MCE_INTERFACE_MANAGEMENT_H_
#define M3AP_MCE_INTERFACE_MANAGEMENT_H_
/*
* Session Start
*/
int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp);
int MCE_send_MBMS_SESSION_START_FAILURE(instance_t instance, m3ap_session_start_failure_t * m3ap_session_start_failure);
/*
* Session Stop
*/
int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* Session Update
*/
int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m3ap_mbms_session_update_resp_t * m3ap_mbms_session_update_resp);
int MCE_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m3ap_mbms_session_update_failure_t * m3ap_mbms_session_update_failure);
int MCE_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp);
/*
* Reset
*/
int MCE_handle_RESET(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_send_RESET_ACKKNOWLEDGE(instance_t instance, M3AP_ResetAcknowledge_t *ResetAcknowledge);
int MCE_send_RESET(instance_t instance, M3AP_Reset_t *Reset);
int MCE_handle_RESET_ACKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* M3AP Setup
*/
int MCE_send_M3_SETUP_REQUEST( m3ap_MCE_instance_t *instance_p, m3ap_MCE_data_t *m3ap_MCE_data_p);
int MCE_handle_M3_SETUP_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_handle_M3_SETUP_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* Error Indication
*/
int MCE_send_ERROR_INDICATION(instance_t instance, M3AP_M3AP_PDU_t *pdu_p);
int MCE_handle_ERROR_INDICATION(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
#endif /* M3AP_MCE_INTERFACE_MANAGEMENT_H_ */
@@ -0,0 +1,257 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_management_procedures.c
* \brief m3ap tasks for MCE
* \author Javier Morgade <javier.morade@ieee.org>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "intertask_interface.h"
#include "assertions.h"
#include "conversions.h"
#include "m3ap_common.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_MCE.h"
#define M3AP_DEBUG_LIST
#ifdef M3AP_DEBUG_LIST
# define M3AP_MCE_LIST_OUT(x, args...) M3AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args)
#else
# define M3AP_MCE_LIST_OUT(x, args...)
#endif
static int indent = 0;
m3ap_MCE_internal_data_t m3ap_MCE_internal_data;
RB_GENERATE(m3ap_mce_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id);
int m3ap_MCE_compare_assoc_id(
struct m3ap_MCE_data_s *p1, struct m3ap_MCE_data_s *p2)
{
if (p1->assoc_id == -1) {
if (p1->cnx_id < p2->cnx_id) {
return -1;
}
if (p1->cnx_id > p2->cnx_id) {
return 1;
}
} else {
if (p1->assoc_id < p2->assoc_id) {
return -1;
}
if (p1->assoc_id > p2->assoc_id) {
return 1;
}
}
/* Matching reference */
return 0;
}
uint16_t m3ap_MCE_fetch_add_global_cnx_id(void)
{
return ++m3ap_MCE_internal_data.global_cnx_id;
}
void m3ap_MCE_prepare_internal_data(void)
{
memset(&m3ap_MCE_internal_data, 0, sizeof(m3ap_MCE_internal_data));
STAILQ_INIT(&m3ap_MCE_internal_data.m3ap_MCE_instances_head);
}
void m3ap_MCE_insert_new_instance(m3ap_MCE_instance_t *new_instance_p)
{
DevAssert(new_instance_p != NULL);
STAILQ_INSERT_TAIL(&m3ap_MCE_internal_data.m3ap_MCE_instances_head,
new_instance_p, m3ap_MCE_entries);
}
void dump_tree_m3(m3ap_MCE_data_t *t)
{
if (t == NULL) return;
printf("-----------------------\n");
printf("MCE id %d %s\n", t->MCE_id, t->MCE_name);
printf("state %d\n", t->state);
printf("nextstream %d\n", t->nextstream);
printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
dump_tree_m3(t->entry.rbe_left);
dump_tree_m3(t->entry.rbe_right);
}
void dump_trees_m3(void)
{
m3ap_MCE_instance_t *zz;
STAILQ_FOREACH(zz, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
m3ap_MCE_entries) {
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
dump_tree_m3(zz->m3ap_mce_head.rbh_root);
printf("---------------------------------------------\n");
}
}
struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id)
{
struct m3ap_MCE_data_s temp;
struct m3ap_MCE_data_s *found;
//printf("m3ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
//dump_trees_m3();
memset(&temp, 0, sizeof(struct m3ap_MCE_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
m3ap_MCE_entries) {
found = RB_FIND(m3ap_mce_map, &instance_p->m3ap_mce_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(m3ap_mce_map, &instance_p->m3ap_mce_head, &temp);
}
return NULL;
}
m3ap_MCE_instance_t *m3ap_MCE_get_instance(instance_t instance)
{
m3ap_MCE_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
m3ap_MCE_entries) {
if (temp->instance == instance) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
/// utility functions
void m3ap_dump_MCE (m3ap_MCE_data_t * MCE_ref);
void
m3ap_dump_MCE_list (void) {
m3ap_MCE_instance_t *inst = NULL;
struct m3ap_MCE_data_s *found = NULL;
struct m3ap_MCE_data_s temp;
memset(&temp, 0, sizeof(struct m3ap_MCE_data_s));
STAILQ_FOREACH (inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
found = RB_FIND(m3ap_mce_map, &inst->m3ap_mce_head, &temp);
m3ap_dump_MCE (found);
}
}
void m3ap_dump_MCE (m3ap_MCE_data_t * MCE_ref) {
if (MCE_ref == NULL) {
return;
}
M3AP_MCE_LIST_OUT ("");
M3AP_MCE_LIST_OUT ("MCE name: %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name);
M3AP_MCE_LIST_OUT ("MCE STATE: %07x", MCE_ref->state);
M3AP_MCE_LIST_OUT ("MCE ID: %07x", MCE_ref->MCE_id);
indent++;
M3AP_MCE_LIST_OUT ("SCTP cnx id: %d", MCE_ref->cnx_id);
M3AP_MCE_LIST_OUT ("SCTP assoc id: %d", MCE_ref->assoc_id);
M3AP_MCE_LIST_OUT ("SCTP instreams: %d", MCE_ref->in_streams);
M3AP_MCE_LIST_OUT ("SCTP outstreams: %d", MCE_ref->out_streams);
indent--;
}
m3ap_MCE_data_t * m3ap_is_MCE_pci_in_list (const uint32_t pci)
{
m3ap_MCE_instance_t *inst;
struct m3ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
RB_FOREACH(elm, m3ap_mce_map, &inst->m3ap_mce_head) {
for (int i = 0; i<elm->num_cc; i++) {
if (elm->Nid_cell[i] == pci) {
return elm;
}
}
}
}
return NULL;
}
m3ap_MCE_data_t * m3ap_is_MCE_id_in_list (const uint32_t MCE_id)
{
m3ap_MCE_instance_t *inst;
struct m3ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
RB_FOREACH(elm, m3ap_mce_map, &inst->m3ap_mce_head) {
if (elm->MCE_id == MCE_id)
return elm;
}
}
return NULL;
}
m3ap_MCE_data_t * m3ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id)
{
m3ap_MCE_instance_t *inst;
struct m3ap_MCE_data_s *found;
struct m3ap_MCE_data_s temp;
temp.assoc_id = sctp_assoc_id;
temp.cnx_id = -1;
STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
found = RB_FIND(m3ap_mce_map, &inst->m3ap_mce_head, &temp);
if (found != NULL){
if (found->assoc_id == sctp_assoc_id) {
return found;
}
}
}
return NULL;
}
@@ -0,0 +1,53 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_management_procedures.h
* \brief m3ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_MCE_MANAGEMENT_PROCEDURES_H_
#define M3AP_MCE_MANAGEMENT_PROCEDURES_H
void m3ap_MCE_prepare_internal_data(void);
void dump_trees_m3(void);
void m3ap_MCE_insert_new_instance(m3ap_MCE_instance_t *new_instance_p);
m3ap_MCE_instance_t *m3ap_MCE_get_instance(uint8_t mod_id);
uint16_t m3ap_MCE_fetch_add_global_cnx_id(void);
m3ap_MCE_data_t* m3ap_is_MCE_id_in_list(uint32_t MCE_id);
m3ap_MCE_data_t* m3ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id);
m3ap_MCE_data_t* m3ap_is_MCE_pci_in_list (const uint32_t pci);
struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id);
#endif /* M3AP_MCE_MANAGEMENT_PROCEDURES_H_ */
+730
View File
@@ -0,0 +1,730 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME.c
* \brief m3ap tasks for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "intertask_interface.h"
#include "m3ap_MME.h"
#include "m3ap_MME_defs.h"
#include "m3ap_MME_management_procedures.h"
#include "m3ap_MME_handler.h"
//#include "m3ap_MME_generate_messages.h"
#include "m3ap_common.h"
#include "m3ap_MME_interface_management.h"
#include "m3ap_ids.h"
#include "m3ap_timers.h"
#include "queue.h"
#include "assertions.h"
#include "conversions.h"
struct m3ap_mme_map;
struct m3ap_MME_data_s;
m3ap_setup_req_t *m3ap_mme_data_from_mce;
RB_PROTOTYPE(m3ap_mme_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id);
static
void m3ap_MME_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
static
void m3ap_MME_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
static
void m3ap_MME_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
//static
//void m3ap_MME_handle_register_MME(instance_t instance,
// m3ap_register_mce_req_t *m3ap_register_MME);
static
void m3ap_MME_register_MME(m3ap_MME_instance_t *instance_p,
net_ip_address_t *target_MME_ip_addr,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t mme_port_for_M3C,
int multi_sd);
//static
//void m3ap_MME_handle_handover_req(instance_t instance,
// m3ap_handover_req_t *m3ap_handover_req);
//
//static
//void m3ap_MME_handle_handover_req_ack(instance_t instance,
// m3ap_handover_req_ack_t *m3ap_handover_req_ack);
//
//static
//void m3ap_MME_ue_context_release(instance_t instance,
// m3ap_ue_context_release_t *m3ap_ue_context_release);
//
static
void m3ap_MME_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
int result;
DevAssert(sctp_data_ind != NULL);
m3ap_MME_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
static
void m3ap_MME_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
DevAssert(sctp_new_association_resp != NULL);
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
LOG_W(M3AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN)
//proto_agent_stop(instance);
//f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return; // exit -1 for debugging
}
// go to an init func
m3ap_mme_data_from_mce = (m3ap_setup_req_t *)calloc(1, sizeof(m3ap_setup_req_t));
// save the assoc id
m3ap_mme_data_from_mce->assoc_id = sctp_new_association_resp->assoc_id;
m3ap_mme_data_from_mce->sctp_in_streams = sctp_new_association_resp->in_streams;
m3ap_mme_data_from_mce->sctp_out_streams = sctp_new_association_resp->out_streams;
// m3ap_MME_instance_t *instance_p;
// m3ap_MME_data_t *m3ap_mme_data_p;
// DevAssert(sctp_new_association_resp != NULL);
// printf("m3ap_MME_handle_sctp_association_resp at 1\n");
// dump_mme_trees_m3();
// instance_p = instance;//m3ap_MME_get_instance(instance);
// DevAssert(instance_p != NULL);
// /* if the assoc_id is already known, it is certainly because an IND was received
// * before. In this case, just update streams and return
// */
// if (sctp_new_association_resp->assoc_id != -1) {
// m3ap_mme_data_p = m3ap_get_MME(instance_p, sctp_new_association_resp->assoc_id,
// sctp_new_association_resp->ulp_cnx_id);
// if (m3ap_mme_data_p != NULL) {
// /* some sanity check - to be refined at some point */
// if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
// M3AP_ERROR("m3ap_mme_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
// abort();
// }
// m3ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
// m3ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
// return;
// }
// }
// m3ap_mme_data_p = m3ap_get_MME(instance_p, -1,
// sctp_new_association_resp->ulp_cnx_id);
// DevAssert(m3ap_mme_data_p != NULL);
// printf("m3ap_MME_handle_sctp_association_resp at 2\n");
// dump_mme_trees_m3();
// if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
// M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
// sctp_new_association_resp->sctp_state,
// instance,
// sctp_new_association_resp->ulp_cnx_id);
// //m3ap_eNB_handle_m3_setup_message(instance_p, m3ap_mme_data_p,
// //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
// return;
// }
// printf("m3ap_MME_handle_sctp_association_resp at 3\n");
// dump_mme_trees_m3();
// /* Update parameters */
// m3ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id;
// m3ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
// m3ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
// printf("m3ap_MME_handle_sctp_association_resp at 4\n");
// dump_mme_trees_m3();
// /* Prepare new m3 Setup Request */
// //m3ap_MME_generate_m3_setup_request(instance_p, m3ap_mme_data_p);
}
static
void m3ap_MME_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
//m3ap_MME_instance_t *instance_p;
//m3ap_MME_data_t *m3ap_mme_data_p;
//printf("m3ap_MME_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
///dump_mme_trees_m3();
///DevAssert(sctp_new_association_ind != NULL);
///instance_p = instance;//m3ap_MME_get_instance(instance);
///DevAssert(instance_p != NULL);
///m3ap_mme_data_p = m3ap_get_MME(instance_p, sctp_new_association_ind->assoc_id, -1);
///if (m3ap_mme_data_p != NULL) abort();
///// DevAssert(m3ap_enb_data_p != NULL);
///if (m3ap_mme_data_p == NULL) {
/// /* Create new MME descriptor */
/// m3ap_mme_data_p = calloc(1, sizeof(*m3ap_mme_data_p));
/// DevAssert(m3ap_mme_data_p != NULL);
/// m3ap_mme_data_p->cnx_id = m3ap_MME_fetch_add_global_cnx_id();
/// m3ap_mme_data_p->m3ap_MME_instance = instance_p;
/// /* Insert the new descriptor in list of known MME
/// * but not yet associated.
/// */
/// RB_INSERT(m3ap_mme_map, &instance_p->m3ap_mme_head, m3ap_mme_data_p);
/// m3ap_mme_data_p->state = M3AP_MME_STATE_CONNECTED;
/// instance_p->m3_target_mme_nb++;
/// if (instance_p->m3_target_mme_pending_nb > 0) {
/// instance_p->m3_target_mme_pending_nb--;
/// }
///} else {
/// M3AP_WARN("m3ap_mme_data_p already exists\n");
///}
///printf("m3ap_MME_handle_sctp_association_ind at 2\n");
///dump_mme_trees_m3();
////* Update parameters */
///m3ap_mme_data_p->assoc_id = sctp_new_association_ind->assoc_id;
///m3ap_mme_data_p->in_streams = sctp_new_association_ind->in_streams;
///m3ap_mme_data_p->out_streams = sctp_new_association_ind->out_streams;
///printf("m3ap_MME_handle_sctp_association_ind at 3\n");
///dump_mme_trees_m3();
}
int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mme_port_for_M3C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = mme_port_for_M3C;
sctp_init->ppid = M3AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
static void m3ap_MME_register_MME(m3ap_MME_instance_t *instance_p,
net_ip_address_t *target_MME_ip_address,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t mme_port_for_M3C,
int multi_sd) {
// MessageDef *message = NULL;
// sctp_new_association_req_multi_t *sctp_new_association_req = NULL;
// m3ap_MME_data_t *m3ap_mme_data = NULL;
// DevAssert(instance_p != NULL);
// DevAssert(target_MME_ip_address != NULL);
// message = itti_alloc_new_message(TASK_M3AP_MME, SCTP_NEW_ASSOCIATION_REQ_MULTI);
// sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
// sctp_new_association_req->port = mme_port_for_M3C;
// sctp_new_association_req->ppid = M3AP_SCTP_PPID;
// sctp_new_association_req->in_streams = in_streams;
// sctp_new_association_req->out_streams = out_streams;
// sctp_new_association_req->multi_sd = multi_sd;
// memcpy(&sctp_new_association_req->remote_address,
// target_MME_ip_address,
// sizeof(*target_MME_ip_address));
// memcpy(&sctp_new_association_req->local_address,
// local_ip_addr,
// sizeof(*local_ip_addr));
// /* Create new MME descriptor */
// m3ap_mme_data = calloc(1, sizeof(*m3ap_mme_data));
// DevAssert(m3ap_mme_data != NULL);
// m3ap_mme_data->cnx_id = m3ap_MME_fetch_add_global_cnx_id();
// sctp_new_association_req->ulp_cnx_id = m3ap_mme_data->cnx_id;
// m3ap_mme_data->assoc_id = -1;
// m3ap_mme_data->m3ap_MME_instance = instance_p;
// /* Insert the new descriptor in list of known MME
// * but not yet associated.
// */
// RB_INSERT(m3ap_mme_map, &instance_p->m3ap_mme_head, m3ap_mme_data);
// m3ap_mme_data->state = M3AP_MME_STATE_WAITING;
// instance_p->m3_target_mme_nb ++;
// instance_p->m3_target_mme_pending_nb ++;
// itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
}
//static
//void m3ap_MME_handle_register_MME(instance_t instance,
// m3ap_register_mce_req_t *m3ap_register_MME) {
// m3ap_MME_instance_t *new_instance;
// DevAssert(m3ap_register_MME != NULL);
// /* Look if the provided instance already exists */
// new_instance = m3ap_MME_get_instance(instance);
//
// if (new_instance != NULL) {
// /* Checks if it is a retry on the same MME */
// DevCheck(new_instance->MME_id == m3ap_register_MME->MME_id, new_instance->MME_id, m3ap_register_MME->MME_id, 0);
// DevCheck(new_instance->cell_type == m3ap_register_MME->cell_type, new_instance->cell_type, m3ap_register_MME->cell_type, 0);
// DevCheck(new_instance->tac == m3ap_register_MME->tac, new_instance->tac, m3ap_register_MME->tac, 0);
// DevCheck(new_instance->mcc == m3ap_register_MME->mcc, new_instance->mcc, m3ap_register_MME->mcc, 0);
// DevCheck(new_instance->mnc == m3ap_register_MME->mnc, new_instance->mnc, m3ap_register_MME->mnc, 0);
// M3AP_WARN("MME[%d] already registered\n", instance);
// } else {
// new_instance = calloc(1, sizeof(m3ap_MME_instance_t));
// DevAssert(new_instance != NULL);
// RB_INIT(&new_instance->m3ap_mme_head);
// /* Copy usefull parameters */
// new_instance->instance = instance;
// new_instance->MME_name = m3ap_register_MME->MME_name;
// new_instance->MME_id = m3ap_register_MME->MME_id;
// new_instance->cell_type = m3ap_register_MME->cell_type;
// new_instance->tac = m3ap_register_MME->tac;
// new_instance->mcc = m3ap_register_MME->mcc;
// new_instance->mnc = m3ap_register_MME->mnc;
// new_instance->mnc_digit_length = m3ap_register_MME->mnc_digit_length;
// new_instance->num_cc = m3ap_register_MME->num_cc;
//
// m3ap_id_manager_init(&new_instance->id_manager);
// m3ap_timers_init(&new_instance->timers,
// m3ap_register_MME->t_reloc_prep,
// m3ap_register_MME->tm3_reloc_overall);
//
// for (int i = 0; i< m3ap_register_MME->num_cc; i++) {
// new_instance->eutra_band[i] = m3ap_register_MME->eutra_band[i];
// new_instance->downlink_frequency[i] = m3ap_register_MME->downlink_frequency[i];
// new_instance->uplink_frequency_offset[i] = m3ap_register_MME->uplink_frequency_offset[i];
// new_instance->Nid_cell[i] = m3ap_register_MME->Nid_cell[i];
// new_instance->N_RB_DL[i] = m3ap_register_MME->N_RB_DL[i];
// new_instance->frame_type[i] = m3ap_register_MME->frame_type[i];
// new_instance->fdd_earfcn_DL[i] = m3ap_register_MME->fdd_earfcn_DL[i];
// new_instance->fdd_earfcn_UL[i] = m3ap_register_MME->fdd_earfcn_UL[i];
// }
//
// DevCheck(m3ap_register_MME->nb_m3 <= M3AP_MAX_NB_MME_IP_ADDRESS,
// M3AP_MAX_NB_MME_IP_ADDRESS, m3ap_register_MME->nb_m3, 0);
// memcpy(new_instance->target_mme_m3_ip_address,
// m3ap_register_MME->target_mme_m3_ip_address,
// m3ap_register_MME->nb_m3 * sizeof(net_ip_address_t));
// new_instance->nb_m3 = m3ap_register_MME->nb_m3;
// new_instance->mme_m3_ip_address = m3ap_register_MME->mme_m3_ip_address;
// new_instance->sctp_in_streams = m3ap_register_MME->sctp_in_streams;
// new_instance->sctp_out_streams = m3ap_register_MME->sctp_out_streams;
// new_instance->mme_port_for_M3C = m3ap_register_MME->mme_port_for_M3C;
// /* Add the new instance to the list of MME (meaningfull in virtual mode) */
// m3ap_MME_insert_new_instance(new_instance);
// M3AP_INFO("Registered new MME[%d] and %s MME id %u\n",
// instance,
// m3ap_register_MME->cell_type == CELL_MACRO_ENB ? "macro" : "home",
// m3ap_register_MME->MME_id);
//
// /* initiate the SCTP listener */
// if (m3ap_MME_init_sctp(new_instance,&m3ap_register_MME->mme_m3_ip_address,m3ap_register_MME->mme_port_for_M3C) < 0 ) {
// M3AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
// return;
// }
//
// M3AP_INFO("MME[%d] MME id %u acting as a listner (server)\n",
// instance, m3ap_register_MME->MME_id);
// }
//}
static
void m3ap_MME_handle_sctp_init_msg_multi_cnf(
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m) {
m3ap_MME_instance_t *instance;
int index;
DevAssert(m != NULL);
instance = m3ap_MME_get_instance(instance_id);
DevAssert(instance != NULL);
instance->multi_sd = m->multi_sd;
/* Exit if CNF message reports failure.
* Failure means multi_sd < 0.
*/
if (instance->multi_sd < 0) {
M3AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n");
DevAssert(instance->multi_sd >= 0);
}
/* Trying to connect to the provided list of MME ip address */
for (index = 0; index < instance->nb_m3; index++) {
M3AP_INFO("MME[%d] MME id %u acting as an initiator (client)\n",
instance_id, instance->MME_id);
m3ap_MME_register_MME(instance,
&instance->target_mme_m3_ip_address[index],
&instance->mme_m3_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->mme_port_for_M3C,
instance->multi_sd);
}
}
//static
//void m3ap_MME_handle_handover_req(instance_t instance,
// m3ap_handover_req_t *m3ap_handover_req)
//{
// m3ap_MME_instance_t *instance_p;
// m3ap_MME_data_t *target;
// m3ap_id_manager *id_manager;
// int ue_id;
//
// int target_pci = m3ap_handover_req->target_physCellId;
//
// instance_p = m3ap_MME_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m3ap_is_MME_pci_in_list(target_pci);
// DevAssert(target != NULL);
//
// /* allocate m3ap ID */
// id_manager = &instance_p->id_manager;
// ue_id = m3ap_allocate_new_id(id_manager);
// if (ue_id == -1) {
// M3AP_ERROR("could not allocate a new M3AP UE ID\n");
// /* TODO: cancel handover: send (to be defined) message to RRC */
// exit(1);
// }
// /* id_source is ue_id, id_target is unknown yet */
// m3ap_set_ids(id_manager, ue_id, m3ap_handover_req->rnti, ue_id, -1);
// m3ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE);
// m3ap_set_reloc_prep_timer(id_manager, ue_id,
// m3ap_timer_get_tti(&instance_p->timers));
// m3ap_id_set_target(id_manager, ue_id, target);
//
// m3ap_MME_generate_m3_handover_request(instance_p, target, m3ap_handover_req, ue_id);
//}
//static
//void m3ap_MME_handle_handover_req_ack(instance_t instance,
// m3ap_handover_req_ack_t *m3ap_handover_req_ack)
//{
// /* TODO: remove this hack (the goal is to find the correct
// * eNodeB structure for the other end) - we need a proper way for RRC
// * and M3AP to identify eNodeBs
// * RRC knows about mod_id and M3AP knows about MME_id (MME_ID in
// * the configuration file)
// * as far as I understand.. CROUX
// */
// m3ap_MME_instance_t *instance_p;
// m3ap_MME_data_t *target;
// int source_assoc_id = m3ap_handover_req_ack->source_assoc_id;
// int ue_id;
// int id_source;
// int id_target;
//
// instance_p = m3ap_MME_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m3ap_get_MME(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// /* rnti is a new information, save it */
// ue_id = m3ap_handover_req_ack->m3_id_target;
// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
// m3ap_set_ids(&instance_p->id_manager, ue_id, m3ap_handover_req_ack->rnti, id_source, id_target);
//
// m3ap_MME_generate_m3_handover_request_ack(instance_p, target, m3ap_handover_req_ack);
//}
//
//static
//void m3ap_MME_ue_context_release(instance_t instance,
// m3ap_ue_context_release_t *m3ap_ue_context_release)
//{
// m3ap_MME_instance_t *instance_p;
// m3ap_MME_data_t *target;
// int source_assoc_id = m3ap_ue_context_release->source_assoc_id;
// int ue_id;
// instance_p = m3ap_MME_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m3ap_get_MME(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// m3ap_MME_generate_m3_ue_context_release(instance_p, target, m3ap_ue_context_release);
//
// /* free the M3AP UE ID */
// ue_id = m3ap_find_id_from_rnti(&instance_p->id_manager, m3ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M3AP_ERROR("could not find UE %x\n", m3ap_ue_context_release->rnti);
// exit(1);
// }
// m3ap_release_id(&instance_p->id_manager, ue_id);
//}
void MME_task_send_sctp_init_req(instance_t enb_id, m3ap_mme_sctp_req_t * m3ap_mme_sctp_req) {
// 1. get the itti msg, and retrive the enb_id from the message
// 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
// 3. creat an itti message to init
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG);
if(m3ap_mme_sctp_req==NULL) {
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n");
message_p->ittiMsg.sctp_init.port = M3AP_PORT_NUMBER;
message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
//message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.8");
}else{
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket) %s\n",m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address);
message_p->ittiMsg.sctp_init.port = m3ap_mme_sctp_req->mme_port_for_M3C;
message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
//message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address);
}
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
}
void *m3ap_MME_task(void *arg) {
MessageDef *received_msg = NULL;
int result;
M3AP_DEBUG("Starting M3AP layer\n");
m3ap_MME_prepare_internal_data();
itti_mark_task_ready(TASK_M3AP_MME);
//MME_task_send_sctp_init_req(0,NULL);
while (1) {
itti_receive_msg(TASK_M3AP_MME, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case MESSAGE_TEST:
LOG_W(M3AP,"MME Received MESSAGE_TEST Message\n");
//MessageDef * message_p = itti_alloc_new_message(TASK_M3AP_MME, MESSAGE_TEST);
//itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p);
break;
case TERMINATE_MESSAGE:
M3AP_WARN(" *** Exiting M3AP thread\n");
itti_exit_task();
break;
// case M3AP_SUBFRAME_PROCESS:
// m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
// break;
//
// case M3AP_REGISTER_MME_REQ:
// LOG_W(M3AP,"MME Received M3AP_REGISTER_MME_REQ Message\n");
// m3ap_MME_handle_register_MME(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_REGISTER_MME_REQ(received_msg));
// break;
//
case M3AP_MME_SCTP_REQ:
MME_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_MME_SCTP_REQ(received_msg));
break;
case M3AP_SETUP_RESP:
LOG_I(M3AP,"MME Received M3AP_SETUP_RESP Message\n");
MME_send_M3_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_SETUP_RESP(received_msg));
break;
// break;
//
// case M3AP_SETUP_FAILURE:
// LOG_W(M3AP,"MME Received M3AP_SETUP_FAILURE Message\n");
// MME_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_SETUP_FAILURE(received_msg));
// break;
//
// case M3AP_MBMS_SCHEDULING_INFORMATION:
// LOG_W(M3AP,"MME Received M3AP_MBMS_SCHEDULING_INFORMATION Message\n");
// MME_send_MBMS_SCHEDULING_INFORMATION(0,
// &M3AP_MBMS_SCHEDULING_INFORMATION(received_msg));
//
case M3AP_MBMS_SESSION_START_REQ:
LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_START_REQ Message\n");
MME_send_MBMS_SESSION_START_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_MBMS_SESSION_START_REQ(received_msg));
break;
//
case M3AP_MBMS_SESSION_STOP_REQ:
LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_STOP_REQ Message\n");
MME_send_MBMS_SESSION_STOP_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M3AP_MBMS_SESSION_STOP_REQ(received_msg));
break;
//
case M3AP_MBMS_SESSION_UPDATE_REQ:
LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_UPDATE_REQ Message\n");
// MME_send_MBMS_SESSION_UPDATE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_MBMS_SESSION_UPDATE_REQ(received_msg));
break;
//
// case M3AP_RESET:
// LOG_W(M3AP,"MME Received M3AP_RESET Message\n");
// MME_send_RESET(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_RESET(received_msg));
// break;
//
// case M3AP_ENB_CONFIGURATION_UPDATE_ACK:
// LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_ACK Message\n");
// MME_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg));
// break;
//
// case M3AP_ENB_CONFIGURATION_UPDATE_FAILURE:
// LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n");
// MME_send_ENB_CONFIGURATION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg))// break;
//
//
// case M3AP_MME_CONFIGURATION_UPDATE:
// LOG_W(M3AP,"MME Received M3AP_MME_CONFIGURATION_UPDATE Message\n");
// MME_send_MME_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_MME_CONFIGURATION_UPDATE(received_msg));
// break;
//
// case M3AP_HANDOVER_REQ:
// m3ap_MME_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_HANDOVER_REQ(received_msg));
// break;
//
// case M3AP_HANDOVER_REQ_ACK:
// m3ap_MME_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_HANDOVER_REQ_ACK(received_msg));
// break;
//
// case M3AP_UE_CONTEXT_RELEASE:
// m3ap_MME_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M3AP_UE_CONTEXT_RELEASE(received_msg));
// break;
//
case SCTP_INIT_MSG_MULTI_CNF:
LOG_E(M3AP,"MME Received SCTP_INIT_MSG_MULTI_CNF Message ... shoudn't be happening ... it doesn't at leaast with M2AP_MCEC\n");
m3ap_MME_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_NEW_ASSOCIATION_RESP:
LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION_RESP Message\n");
m3ap_MME_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
break;
case SCTP_NEW_ASSOCIATION_IND:
LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION Message\n");
m3ap_MME_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_ind);
break;
case SCTP_DATA_IND:
LOG_D(M3AP,"MME Received SCTP_DATA_IND Message\n");
m3ap_MME_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_data_ind);
break;
default:
M3AP_ERROR("MME Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
}
return NULL;
}
#include "common/config/config_userapi.h"
int is_m3ap_MME_enabled(void)
{
static volatile int config_loaded = 0;
static volatile int enabled = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if (pthread_mutex_lock(&mutex)) goto mutex_error;
if (config_loaded) {
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
}
char *enable_m3 = NULL;
paramdef_t p[] = {
{ "enable_mme_m3", "yes/no", 0, strptr:&enable_m3, defstrval:"", TYPE_STRING, 0 }
};
/* TODO: do it per module - we check only first MME */
config_get(p, sizeof(p)/sizeof(paramdef_t), "MMEs.[0]");
if (enable_m3 != NULL && strcmp(enable_m3, "yes") == 0)
enabled = 1;
config_loaded = 1;
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
mutex_error:
LOG_E(M3AP, "mutex error\n");
exit(1);
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME.h
* \brief m3ap tasks for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M3AP_MME_H_
#define M3AP_MME_H_
#include "m3ap_MME_defs.h"
int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M3C);
void *m3ap_MME_task(void *arg);
int is_m3ap_MME_enabled(void);
#endif /* M3AP_MCE_H_ */
/**
* @}
*/
+210
View File
@@ -0,0 +1,210 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME_defs.h
* \brief m2ap struct definitions for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "m3ap_ids.h" //looks X2AP specific for HO
#include "m3ap_timers.h"
#ifndef M3AP_MME_DEFS_H_
#define M3AP_MME_DEFS_H_
#define M3AP_MME_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M3AP_MME_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target MME accepts or
* M2 Setup failure if rejects the MME.
*/
M3AP_MME_STATE_WAITING = 0x1,
/* The MME is successfully connected to another MME. */
M3AP_MME_STATE_CONNECTED = 0x2,
/* M3AP is ready, and the MME is successfully connected to another MME. */
M3AP_MME_STATE_READY = 0x3,
M3AP_MME_STATE_OVERLOAD = 0x4,
M3AP_MME_STATE_RESETTING = 0x5,
/* Max number of states available */
M3AP_MME_STATE_MAX,
} m3ap_MME_state_t;
/* Served PLMN identity element */
/*struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};*/
/* Served group id element */
/*struct served_group_id_s {
uint16_t mce_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};*/
/* Served enn code for a particular MME */
/*struct mce_code_s {
uint8_t mce_code;
STAILQ_ENTRY(mce_code_s) next;
};*/
struct m3ap_MME_instance_s;
/* This structure describes association of a MME to another MME */
typedef struct m3ap_MME_data_s {
/* MME descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m3ap_MME_data_s) entry;
/* This is the optional name provided by the MME */
char *MME_name;
/* target MME ID */
uint32_t MME_id;
/* Current MME load information (if any). */
//m3ap_load_state_t overload_state;
/* Current MME->MME M3AP association state */
m3ap_MME_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/M3AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/* Only meaningfull in virtual mode */
struct m3ap_MME_instance_s *m3ap_MME_instance;
} m3ap_MME_data_t;
typedef struct m3ap_MME_instance_s {
/* used in simulation to store multiple MME instances*/
STAILQ_ENTRY(m3ap_MME_instance_s) m3ap_MME_entries;
/* Number of target MMEs requested by MME (tree size) */
uint32_t m2_target_mce_nb;
/* Number of target MMEs for which association is pending */
uint32_t m2_target_mce_pending_nb;
/* Number of target MME successfully associated to MME */
uint32_t m2_target_mce_associated_nb;
/* Tree of M3AP MME associations ordered by association ID */
RB_HEAD(m3ap_mme_map, m3ap_MME_data_s) m3ap_mme_head;
/* Tree of UE ordered by MME_ue_m3ap_id's */
// RB_HEAD(m3ap_ue_map, m3ap_MME_ue_context_s) m3ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of MME */
char *MME_name;
/* Unique MME_id to identify the MME within EPC.
* In our case the MME is a macro MME so the id will be 20 bits long.
* For Home MME id, this field should be 28 bits long.
*/
uint32_t MME_id;
/* The type of the cell */
cell_type_t cell_type;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* CC params */
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MME_IP_ADDRESS];
uint8_t nb_m3;
net_ip_address_t mme_m3_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t mme_port_for_M3C;
int multi_sd;
m3ap_id_manager id_manager;
m3ap_timers_t timers;
} m3ap_MME_instance_t;
typedef struct {
/* List of served MMEs
* Only used for virtual mode
*/
STAILQ_HEAD(m3ap_MME_instances_head_s, m3ap_MME_instance_s) m3ap_MME_instances_head;
/* Nb of registered MMEs */
uint8_t nb_registered_MMEs;
/* Generate a unique connexion id used between M3AP and SCTP */
uint16_t global_cnx_id;
} m3ap_MME_internal_data_t;
int m3ap_MME_compare_assoc_id(struct m3ap_MME_data_s *p1, struct m3ap_MME_data_s *p2);
/* Generate the tree management functions */
struct m3ap_MME_map;
struct m3ap_MME_data_s;
RB_PROTOTYPE(m3ap_MME_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id);
#endif /* M3AP_MME_DEFS_H_ */
+804
View File
@@ -0,0 +1,804 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_MCE_generate_messages.c
* \brief m2ap procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include "intertask_interface.h"
//#include "M2AP_LastVisitedCell-Item.h"
#include "m2ap_common.h"
#include "m2ap_MCE.h"
#include "m2ap_MCE_generate_messages.h"
#include "m2ap_encoder.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
#include "m2ap_itti_messaging.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
int m2ap_MCE_generate_m2_setup_request(
m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p)
{
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupRequest_t *out;
M2AP_M2SetupRequest_Ies_t *ie;
//M2AP_PLMN_Identity_t *plmn;
//ServedCells__Member *servedCellMember;
//M2AP_GU_Group_ID_t *gu;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(m2ap_MCE_data_p != NULL);
m2ap_MCE_data_p->state = M2AP_MCE_STATE_WAITING;
/* Prepare the M2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
/* mandatory */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GlobalMCE_ID;
//MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GlobalMCE_ID.pLMN_Identity);
//ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID;
//MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id,
// &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID);
//M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_ServedCells;
//{
// for (int i = 0; i<instance_p->num_cc; i++){
// servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
// {
// servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
// &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
// INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
// plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
// ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
// }
// if (instance_p->frame_type[i] == FDD) {
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
// switch (instance_p->N_RB_DL[i]) {
// case 6:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// break;
// case 15:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// break;
// case 25:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// break;
// case 50:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// break;
// case 75:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// break;
// case 100:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// break;
// default:
// AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
// break;
// }
// }
// else {
// AssertFatal(0,"M2Setuprequest not supported for TDD!");
// }
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
// }
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GUGroupIDList;
//{
// gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &gu->pLMN_Identity);
// //@TODO: consider to update this value
// INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
M2AP_ERROR("Failed to encode M2 setup request\n");
return -1;
}
//MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0);
return ret;
}
int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p)
{
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupResponse_t *out;
M2AP_M2SetupResponse_Ies_t *ie;
//M2AP_PLMN_Identity_t *plmn;
//ServedCells__Member *servedCellMember;
//M2AP_GU_Group_ID_t *gu;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(m2ap_MCE_data_p != NULL);
/* Prepare the M2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
/* mandatory */
ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalMCE_ID;
//MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GlobalMCE_ID.pLMN_Identity);
//ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID;
//MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id,
// &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID);
//M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells;
//{
// for (int i = 0; i<instance_p->num_cc; i++){
// servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
// {
// servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
// &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
// INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
// plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
// ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
// }
// if (instance_p->frame_type[i] == FDD) {
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
// switch (instance_p->N_RB_DL[i]) {
// case 6:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// break;
// case 15:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// break;
// case 25:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// break;
// case 50:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// break;
// case 75:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// break;
// case 100:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// break;
// default:
// AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
// break;
// }
// }
// else {
// AssertFatal(0,"M2Setupresponse not supported for TDD!");
// }
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
// }
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList;
//{
// gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &gu->pLMN_Identity);
// //@TODO: consider to update this value
// INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
M2AP_ERROR("Failed to encode M2 setup response\n");
return -1;
}
m2ap_MCE_data_p->state = M2AP_MCE_STATE_READY;
//MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id);
m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0);
return ret;
}
int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait)
{
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupFailure_t *out;
M2AP_M2SetupFailure_Ies_t *ie;
uint8_t *buffer;
uint32_t len;
int ret = 0;
/* Prepare the M2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
/* mandatory */
ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_Cause;
//ie->criticality = M2AP_Criticality_ignore;
//ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause;
//m2ap_MCE_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* optional: consider to handle this later */
ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_TimeToWait;
//ie->criticality = M2AP_Criticality_ignore;
//ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait;
//if (time_to_wait > -1) {
// ie->value.choice.TimeToWait = time_to_wait;
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
M2AP_ERROR("Failed to encode M2 setup failure\n");
return -1;
}
//MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE,
// MSC_M2AP_TARGET_MCE, NULL, 0,
// "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u",
// assoc_id, cause_type, cause_value);
m2ap_MCE_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
return ret;
}
int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value)
{
DevAssert (cause_p != NULL);
cause_p->present = cause_type;
switch (cause_type) {
case M2AP_Cause_PR_radioNetwork:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_transport:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_protocol:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_misc:
cause_p->choice.misc = cause_value;
break;
default:
return -1;
}
return 0;
}
//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequest_t *out;
// M2AP_HandoverRequest_IEs_t *ie;
// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause;
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.ECGI.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(m2ap_MCE_data_p->MCE_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
// //@TODO: consider to update these values
// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
// //@TODO: consider to update this value
// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id;
//
// KMCE_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
//
// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc;
// }
// else {
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
// }
//
// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
//
// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
//
// //@TODO: update with proper UEAMPR
// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
// {
// for (int i=0;i<m2ap_handover_req->nb_e_rabs_tobesetup;i++) {
// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t));
// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
// {
// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length/8);
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length%8;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
// m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.buffer,
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
// }
// }
//
// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
// //@TODO: consider to update this value
// {
// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t));
// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small;
// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover request\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequestAcknowledge_t *out;
// M2AP_HandoverRequestAcknowledge_IEs_t *ie;
// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs;
// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// ue_id = m2ap_handover_req_ack->m2_id_target;
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
//
// {
// for (int i=0;i<m2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t));
// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
// {
// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
// }
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargetMCEtoSource_MCETransparentContainer;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargetMCEtoSource_MCETransparentContainer;
//
// OCTET_STRING_fromBuf(&ie->value.choice.TargetMCEtoSource_MCETransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover response\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_UEContextRelease_t *out;
// M2AP_UEContextRelease_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
// exit(1);
// }
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP ue context relase message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease;
// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 UE Context Release\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverCancel_t *out;
// M2AP_HandoverCancel_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// ue_id = m2_ue_id;
// id_source = ue_id;
// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id);
//
// /* Prepare the M2AP handover cancel message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional */
// if (id_target != -1) {
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// }
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause;
// switch (cause) {
// case M2AP_T_RELOC_PREP_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_trelocprep_expiry;
// break;
// case M2AP_TX2_RELOC_OVERALL_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_tx2relocoverall_expiry;
// break;
// default:
// /* we can't come here */
// M2AP_ERROR("unhandled cancel cause\n");
// exit(1);
// }
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 Handover Cancel\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
@@ -0,0 +1,63 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_MCE_generate_messages.h
* \brief m2ap procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_GENERATE_MESSAGES_H_
#define M2AP_MCE_GENERATE_MESSAGES_H_
#include "m2ap_MCE_defs.h"
#include "m2ap_common.h"
int m2ap_MCE_generate_m2_setup_request(m2ap_MCE_instance_t *instance_p,
m2ap_MCE_data_t *m2ap_MCE_data_p);
int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p);
int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait);
int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value);
//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id);
//
//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause);
#endif /* M2AP_MCE_GENERATE_MESSAGES_H_ */
+118
View File
@@ -0,0 +1,118 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB_handler.c
* \brief m3ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m3ap_common.h"
#include "m3ap_MME_defs.h"
#include "m3ap_handler.h"
#include "m3ap_decoder.h"
#include "m3ap_ids.h"
#include "m3ap_MME_management_procedures.h"
//#include "m3ap_MCE_generate_messages.h"
#include "m3ap_MME_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m3ap_MCE_message_decoded_callback m3ap_MME_messages_callback[][3] = {
{ 0, MME_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */
{ 0, MME_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ 0, 0, 0 }, /* ??? */
{ 0, MME_handle_MBMS_SESSION_UPDATE_RESPONSE, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ MME_handle_M3_SETUP_REQUEST, 0, 0 } /* M3 Setup */
};
static char *m3ap_direction2String(int m3ap_dir) {
static char *m3ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m3ap_direction_String[m3ap_dir]);
}
int m3ap_MME_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M3AP_M3AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m3ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M3AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_MME_messages_callback) / (3 * sizeof(
m3ap_message_decoded_callback))
|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m3ap_MME_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m3ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M3AP, "Calling handler with instance %d\n",instance);
ret = (*m3ap_MME_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return ret;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_handler.h
* \brief m3ap handler procedures for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_MME_HANDLERS_H_
#define M3AP_MME_HANDLERS_H_
#include "m3ap_MME_defs.h"
//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
//const uint8_t * const data, const uint32_t data_length);
int m3ap_MME_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
#endif /* M3AP_MME_HANDLERS_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,111 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME_interface_management.h
* \brief m3ap interface management for MME
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M3AP_MME_INTERFACE_MANAGEMENT_H_
#define M3AP_MME_INTERFACE_MANAGEMENT_H_
/*
* MBMS Session start
*/
int MME_send_MBMS_SESSION_START_REQUEST(instance_t instance/*,
uint32_t assoc_id*/,m3ap_session_start_req_t* m3ap_session_start_req);
int MME_handle_MBMS_SESSION_START_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MME_handle_MBMS_SESSION_START_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* MBMS Session stop
*/
int MME_send_MBMS_SESSION_STOP_REQUEST(instance_t instance,
m3ap_session_stop_req_t* m3ap_session_stop_req);
int MME_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* Update
*/
int MME_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MME_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* Reset
*/
int MME_send_RESET(instance_t instance, m3ap_reset_t * m3ap_reset);
int MME_handle_RESET_ACKKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MME_handle_RESET(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MME_send_RESET_ACKNOWLEDGE(instance_t instance, M3AP_ResetAcknowledge_t *ResetAcknowledge);
/*
* M3AP Setup
*/
int MME_handle_M3_SETUP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MME_send_M3_SETUP_RESPONSE(instance_t instance,/*uint32_t assoc_id,*/ m3ap_setup_resp_t *m3ap_setup_resp);
int MME_send_M3_SETUP_FAILURE(instance_t instance, /*uint32_t assoc_id*/ m3ap_setup_failure_t * m3ap_setup_failure);
#endif /* M3AP_MME_INTERFACE_MANAGEMENT_H_ */
@@ -0,0 +1,257 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME_management_procedures.c
* \brief m3ap tasks for MME
* \author Javier Morgade <javier.morade@ieee.org>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "intertask_interface.h"
#include "assertions.h"
#include "conversions.h"
#include "m3ap_common.h"
#include "m3ap_MME_defs.h"
#include "m3ap_MME.h"
#define M3AP_DEBUG_LIST
#ifdef M3AP_DEBUG_LIST
# define M3AP_MME_LIST_OUT(x, args...) M3AP_DEBUG("[MME]%*s"x"\n", 4*indent, "", ##args)
#else
# define M3AP_MME_LIST_OUT(x, args...)
#endif
static int indent = 0;
m3ap_MME_internal_data_t m3ap_MME_internal_data;
RB_GENERATE(m3ap_mme_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id);
int m3ap_MME_compare_assoc_id(
struct m3ap_MME_data_s *p1, struct m3ap_MME_data_s *p2)
{
if (p1->assoc_id == -1) {
if (p1->cnx_id < p2->cnx_id) {
return -1;
}
if (p1->cnx_id > p2->cnx_id) {
return 1;
}
} else {
if (p1->assoc_id < p2->assoc_id) {
return -1;
}
if (p1->assoc_id > p2->assoc_id) {
return 1;
}
}
/* Matching reference */
return 0;
}
uint16_t m3ap_MME_fetch_add_global_cnx_id(void)
{
return ++m3ap_MME_internal_data.global_cnx_id;
}
void m3ap_MME_prepare_internal_data(void)
{
memset(&m3ap_MME_internal_data, 0, sizeof(m3ap_MME_internal_data));
STAILQ_INIT(&m3ap_MME_internal_data.m3ap_MME_instances_head);
}
void m3ap_MME_insert_new_instance(m3ap_MME_instance_t *new_instance_p)
{
DevAssert(new_instance_p != NULL);
STAILQ_INSERT_TAIL(&m3ap_MME_internal_data.m3ap_MME_instances_head,
new_instance_p, m3ap_MME_entries);
}
void dump_mme_tree_m2(m3ap_MME_data_t *t)
{
if (t == NULL) return;
printf("-----------------------\n");
printf("MME id %d %s\n", t->MME_id, t->MME_name);
printf("state %d\n", t->state);
printf("nextstream %d\n", t->nextstream);
printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
dump_mme_tree_m2(t->entry.rbe_left);
dump_mme_tree_m2(t->entry.rbe_right);
}
void dump_mme_trees_m2(void)
{
m3ap_MME_instance_t *zz;
STAILQ_FOREACH(zz, &m3ap_MME_internal_data.m3ap_MME_instances_head,
m3ap_MME_entries) {
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
dump_mme_tree_m2(zz->m3ap_mme_head.rbh_root);
printf("---------------------------------------------\n");
}
}
struct m3ap_MME_data_s *m3ap_get_MME(m3ap_MME_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id)
{
struct m3ap_MME_data_s temp;
struct m3ap_MME_data_s *found;
printf("m3ap_get_MME at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
dump_mme_trees_m2();
memset(&temp, 0, sizeof(struct m3ap_MME_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &m3ap_MME_internal_data.m3ap_MME_instances_head,
m3ap_MME_entries) {
found = RB_FIND(m3ap_mme_map, &instance_p->m3ap_mme_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(m3ap_mme_map, &instance_p->m3ap_mme_head, &temp);
}
return NULL;
}
m3ap_MME_instance_t *m3ap_MME_get_instance(instance_t instance)
{
m3ap_MME_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &m3ap_MME_internal_data.m3ap_MME_instances_head,
m3ap_MME_entries) {
if (temp->instance == instance) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
/// utility functions
void m3ap_dump_MME (m3ap_MME_data_t * MME_ref);
void
m3ap_dump_MME_list (void) {
m3ap_MME_instance_t *inst = NULL;
struct m3ap_MME_data_s *found = NULL;
struct m3ap_MME_data_s temp;
memset(&temp, 0, sizeof(struct m3ap_MME_data_s));
STAILQ_FOREACH (inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) {
found = RB_FIND(m3ap_mme_map, &inst->m3ap_mme_head, &temp);
m3ap_dump_MME (found);
}
}
void m3ap_dump_MME (m3ap_MME_data_t * MME_ref) {
if (MME_ref == NULL) {
return;
}
M3AP_MME_LIST_OUT ("");
M3AP_MME_LIST_OUT ("MME name: %s", MME_ref->MME_name == NULL ? "not present" : MME_ref->MME_name);
M3AP_MME_LIST_OUT ("MME STATE: %07x", MME_ref->state);
M3AP_MME_LIST_OUT ("MME ID: %07x", MME_ref->MME_id);
indent++;
M3AP_MME_LIST_OUT ("SCTP cnx id: %d", MME_ref->cnx_id);
M3AP_MME_LIST_OUT ("SCTP assoc id: %d", MME_ref->assoc_id);
M3AP_MME_LIST_OUT ("SCTP instreams: %d", MME_ref->in_streams);
M3AP_MME_LIST_OUT ("SCTP outstreams: %d", MME_ref->out_streams);
indent--;
}
m3ap_MME_data_t * m3ap_is_MME_pci_in_list (const uint32_t pci)
{
m3ap_MME_instance_t *inst;
struct m3ap_MME_data_s *elm;
STAILQ_FOREACH(inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) {
RB_FOREACH(elm, m3ap_mme_map, &inst->m3ap_mme_head) {
for (int i = 0; i<elm->num_cc; i++) {
if (elm->Nid_cell[i] == pci) {
return elm;
}
}
}
}
return NULL;
}
m3ap_MME_data_t * m3ap_is_MME_id_in_list (const uint32_t MME_id)
{
m3ap_MME_instance_t *inst;
struct m3ap_MME_data_s *elm;
STAILQ_FOREACH(inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) {
RB_FOREACH(elm, m3ap_mme_map, &inst->m3ap_mme_head) {
if (elm->MME_id == MME_id)
return elm;
}
}
return NULL;
}
m3ap_MME_data_t * m3ap_is_MME_assoc_id_in_list (const uint32_t sctp_assoc_id)
{
m3ap_MME_instance_t *inst;
struct m3ap_MME_data_s *found;
struct m3ap_MME_data_s temp;
temp.assoc_id = sctp_assoc_id;
temp.cnx_id = -1;
STAILQ_FOREACH(inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) {
found = RB_FIND(m3ap_mme_map, &inst->m3ap_mme_head, &temp);
if (found != NULL){
if (found->assoc_id == sctp_assoc_id) {
return found;
}
}
}
return NULL;
}
@@ -0,0 +1,54 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB_management_procedures.h
* \brief m3ap tasks for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_MME_MANAGEMENT_PROCEDURES_H_
#define M3AP_MME_MANAGEMENT_PROCEDURES_H
void m3ap_MME_prepare_internal_data(void);
void dump_trees_m2(void);
void m3ap_MME_insert_new_instance(m3ap_MME_instance_t *new_instance_p);
m3ap_MME_instance_t *m3ap_MME_get_instance(uint8_t mod_id);
uint16_t m3ap_MME_fetch_add_global_cnx_id(void);
void m3ap_MME_prepare_internal_data(void);
m3ap_MME_data_t* m3ap_is_MME_id_in_list(uint32_t MME_id);
m3ap_MME_data_t* m3ap_is_MME_assoc_id_in_list(uint32_t sctp_assoc_id);
m3ap_MME_data_t* m3ap_is_MME_pci_in_list (const uint32_t pci);
struct m3ap_MME_data_s *m3ap_get_MME(m3ap_MME_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id);
#endif /* M3AP_MME_MANAGEMENT_PROCEDURES_H_ */
+124
View File
@@ -0,0 +1,124 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_common.c
* \brief m3ap procedures for both eNB and MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "m3ap_common.h"
#include "M3AP_M3AP-PDU.h"
int asn_debug = 0;
int asn1_xer_print = 0;
#if defined(EMIT_ASN_DEBUG_EXTERN)
inline void ASN_DEBUG(const char *fmt, ...)
{
if (asn_debug) {
int adi = asn_debug_indent;
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "[ASN1]");
while(adi--) fprintf(stderr, " ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
}
#endif
ssize_t m3ap_generate_initiating_message(
uint8_t **buffer,
uint32_t *length,
M3AP_ProcedureCode_t procedureCode,
M3AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr)
{
M3AP_M3AP_PDU_t pdu;
ssize_t encoded;
memset(&pdu, 0, sizeof(M3AP_M3AP_PDU_t));
pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage.procedureCode = procedureCode;
pdu.choice.initiatingMessage.criticality = criticality;
ANY_fromType_aper((ANY_t *)&pdu.choice.initiatingMessage.value, td, sptr);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)&pdu);
}
/* We can safely free list of IE from sptr */
ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr);
if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, &pdu,
(void **)buffer)) < 0) {
return -1;
}
*length = encoded;
return encoded;
}
ssize_t m3ap_generate_unsuccessfull_outcome(
uint8_t **buffer,
uint32_t *length,
M3AP_ProcedureCode_t procedureCode,
M3AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr)
{
M3AP_M3AP_PDU_t pdu;
ssize_t encoded;
memset(&pdu, 0, sizeof(M3AP_M3AP_PDU_t));
pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome;
pdu.choice.successfulOutcome.procedureCode = procedureCode;
pdu.choice.successfulOutcome.criticality = criticality;
ANY_fromType_aper((ANY_t *)&pdu.choice.successfulOutcome.value, td, sptr);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)&pdu);
}
/* We can safely free list of IE from sptr */
ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr);
if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, &pdu,
(void **)buffer)) < 0) {
return -1;
}
*length = encoded;
return encoded;
}
void m3ap_handle_criticality(M3AP_Criticality_t criticality)
{
}
+175
View File
@@ -0,0 +1,175 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#if HAVE_CONFIG_H_
# include "config.h"
#endif
#include "M3AP_ProtocolIE-Field.h"
#include "M3AP_M3AP-PDU.h"
#include "M3AP_InitiatingMessage.h"
#include "M3AP_SuccessfulOutcome.h"
#include "M3AP_UnsuccessfulOutcome.h"
#include "M3AP_ProtocolIE-FieldPair.h"
#include "M3AP_ProtocolIE-ContainerPair.h"
#include "M3AP_ProtocolExtensionField.h"
#include "M3AP_ProtocolExtensionContainer.h"
#include "M3AP_asn_constant.h"
#include "intertask_interface.h"
#ifndef M3AP_COMMON_H_
#define M3AP_COMMON_H_
/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
/* Checking version of ASN1C compiler */
#if (ASN1C_ENVIRONMENT_VERSION < 923)
# error "You are compiling m3ap with the wrong version of ASN1C"
#endif
#ifndef M3AP_PORT
# define M3AP_PORT 36444
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
extern int asn1_xer_print;
#if defined(ENB_MODE)
# include "common/utils/LOG/log.h"
# include "m3ap_default_values.h"
# define M3AP_INFO(x, args...) LOG_I(M3AP, x, ##args)
# define M3AP_ERROR(x, args...) LOG_E(M3AP, x, ##args)
# define M3AP_WARN(x, args...) LOG_W(M3AP, x, ##args)
# define M3AP_DEBUG(x, args...) LOG_D(M3AP, x, ##args)
#else
# define M3AP_INFO(x, args...) do { fprintf(stdout, "[M3AP][I]"x, ##args); } while(0)
# define M3AP_ERROR(x, args...) do { fprintf(stdout, "[M3AP][E]"x, ##args); } while(0)
# define M3AP_WARN(x, args...) do { fprintf(stdout, "[M3AP][W]"x, ##args); } while(0)
# define M3AP_DEBUG(x, args...) do { fprintf(stdout, "[M3AP][D]"x, ##args); } while(0)
#endif
#define M3AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
do {\
IE_TYPE **ptr; \
ie = NULL; \
for (ptr = container->protocolIEs.list.array; \
ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \
ptr++) { \
if((*ptr)->id == IE_ID) { \
ie = *ptr; \
break; \
} \
} \
if (mandatory) DevAssert(ie != NULL); \
} while(0)
/** \brief Function callback prototype.
**/
typedef int (*m3ap_message_decoded_callback)(
instance_t instance,
uint32_t assocId,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/** \brief Function callback prototype.
**/
typedef int (*m3ap_MCE_message_decoded_callback)(
instance_t instance,
uint32_t assocId,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/** \brief Function callback prototype.
**/
typedef int (*m3ap_MME_message_decoded_callback)(
instance_t instance,
uint32_t assocId,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/** \brief Encode a successfull outcome message
\param buffer pointer to buffer in which data will be encoded
\param length pointer to the length of buffer
\param procedureCode Procedure code for the message
\param criticality Criticality of the message
\param td ASN1C type descriptor of the sptr
\param sptr Deferenced pointer to the structure to encode
@returns size in bytes encded on success or 0 on failure
**/
ssize_t m3ap_generate_successfull_outcome(
uint8_t **buffer,
uint32_t *length,
M3AP_ProcedureCode_t procedureCode,
M3AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr);
/** \brief Encode an initiating message
\param buffer pointer to buffer in which data will be encoded
\param length pointer to the length of buffer
\param procedureCode Procedure code for the message
\param criticality Criticality of the message
\param td ASN1C type descriptor of the sptr
\param sptr Deferenced pointer to the structure to encode
@returns size in bytes encded on success or 0 on failure
**/
ssize_t m3ap_generate_initiating_message(
uint8_t **buffer,
uint32_t *length,
M3AP_ProcedureCode_t procedureCode,
M3AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr);
/** \brief Encode an unsuccessfull outcome message
\param buffer pointer to buffer in which data will be encoded
\param length pointer to the length of buffer
\param procedureCode Procedure code for the message
\param criticality Criticality of the message
\param td ASN1C type descriptor of the sptr
\param sptr Deferenced pointer to the structure to encode
@returns size in bytes encded on success or 0 on failure
**/
ssize_t m3ap_generate_unsuccessfull_outcome(
uint8_t **buffer,
uint32_t *length,
M3AP_ProcedureCode_t procedureCode,
M3AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr);
/** \brief Handle criticality
\param criticality Criticality of the IE
@returns void
**/
void m3ap_handle_criticality(M3AP_Criticality_t criticality);
#endif /* M3AP_COMMON_H_ */
+217
View File
@@ -0,0 +1,217 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_decoder.c
* \brief m3ap decoder procedures
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include "assertions.h"
#include "intertask_interface.h"
#include "m3ap_common.h"
#include "m3ap_decoder.h"
static int m3ap_decode_initiating_message(M3AP_M3AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.initiatingMessage.procedureCode) {
case M3AP_ProcedureCode_id_mBMSsessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mBMSsessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_errorIndication:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_privateMessage:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_Reset:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mBMSsessionUpdate:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mCEConfigurationUpdate:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_m3Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
default:
M3AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
return -1;
}
return 0;
}
static int m3ap_decode_successful_outcome(M3AP_M3AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.successfulOutcome.procedureCode) {
case M3AP_ProcedureCode_id_mBMSsessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_successfuloutcome_message!\n");
break;
case M3AP_ProcedureCode_id_mBMSsessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_succesfuloutcome_message!\n");
break;
case M3AP_ProcedureCode_id_errorIndication:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_privateMessage:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_Reset:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mBMSsessionUpdate:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mCEConfigurationUpdate:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_m3Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_succesfuloutcome_message!\n");
break;
default:
M3AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
(int)pdu->choice.successfulOutcome.procedureCode);
return -1;
}
return 0;
}
static int m3ap_decode_unsuccessful_outcome(M3AP_M3AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.unsuccessfulOutcome.procedureCode) {
case M3AP_ProcedureCode_id_mBMSsessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mBMSsessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_errorIndication:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_privateMessage:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_Reset:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mBMSsessionUpdate:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_mCEConfigurationUpdate:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
case M3AP_ProcedureCode_id_m3Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu);
M3AP_INFO("m3ap__decode_initiating_message!\n");
break;
default:
M3AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
(int)pdu->choice.unsuccessfulOutcome.procedureCode);
return -1;
}
return 0;
}
int m3ap_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
{
asn_dec_rval_t dec_ret;
DevAssert(buffer != NULL);
dec_ret = aper_decode(NULL,
&asn_DEF_M3AP_M3AP_PDU,
(void **)&pdu,
buffer,
length,
0,
0);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, pdu);
}
if (dec_ret.code != RC_OK) {
M3AP_ERROR("Failed to decode pdu\n");
return -1;
}
switch(pdu->present) {
case M3AP_M3AP_PDU_PR_initiatingMessage:
return m3ap_decode_initiating_message(pdu);
case M3AP_M3AP_PDU_PR_successfulOutcome:
return m3ap_decode_successful_outcome(pdu);
case M3AP_M3AP_PDU_PR_unsuccessfulOutcome:
return m3ap_decode_unsuccessful_outcome(pdu);
default:
M3AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present);
break;
}
return -1;
}
+35
View File
@@ -0,0 +1,35 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_decoder.h
* \brief m3ap decoder procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_DECODER_H_
#define M3AP_DECODER_H_
int m3ap_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
__attribute__ ((warn_unused_result));
#endif /* M3AP_DECODER_H_ */
+47
View File
@@ -0,0 +1,47 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_default_values.h
* \brief default values for m3ap procedures
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M3AP_DEFAULT_VALUES_H_
#define M3AP_DEFAULT_VALUES_H_
#define ENB_TAC (1)
#define ENB_MCC (208)
#define ENB_MNC (92)
#define ENB_NAME "Eurecom ENB"
#define ENB_NAME_FORMAT (ENB_NAME" %u")
#define M3AP_PORT_NUMBER (36444)
#define M3AP_SCTP_PPID (44)
#endif /* M3AP_DEFAULT_VALUES_H_ */
+61
View File
@@ -0,0 +1,61 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_encoder.c
* \brief m3ap encoder procedures
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "assertions.h"
#include "conversions.h"
#include "intertask_interface.h"
#include "m3ap_common.h"
#include "m3ap_encoder.h"
int m3ap_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
{
ssize_t encoded;
DevAssert(pdu != NULL);
DevAssert(buffer != NULL);
DevAssert(len != NULL);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)pdu);
}
encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, pdu, (void **)buffer);
if (encoded < 0) {
return -1;
}
*len = encoded;
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, pdu);
return encoded;
}
+35
View File
@@ -0,0 +1,35 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_encoder.h
* \brief m3ap encoder procedures
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_ENCODER_H_
#define M3AP_ENCODER_H_
int m3ap_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
__attribute__ ((warn_unused_result));
#endif /* M3AP_ENCODER_H_ */
+123
View File
@@ -0,0 +1,123 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB_handler.c
* \brief m3ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m3ap_common.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_handler.h"
#include "m3ap_decoder.h"
#include "m3ap_ids.h"
#include "m3ap_MCE_management_procedures.h"
//#include "m3ap_MCE_generate_messages.h"
#include "m3ap_MME_interface_management.h"
#include "m3ap_MCE_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m3ap_message_decoded_callback m3ap_messages_callback[][3] = {
{ MCE_handle_MBMS_SESSION_START_REQUEST, MME_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */
{ MCE_handle_MBMS_SESSION_STOP_REQUEST, MME_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ 0, 0, 0 }, /* ??? */
{ MCE_handle_MBMS_SESSION_UPDATE_REQUEST, MME_handle_MBMS_SESSION_UPDATE_RESPONSE, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ MME_handle_M3_SETUP_REQUEST, MCE_handle_M3_SETUP_RESPONSE, 0 } /* M3 Setup */
};
char *m3ap_direction2String(int m3ap_dir) {
static char *m3ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m3ap_direction_String[m3ap_dir]);
}
int m3ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M3AP_M3AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
int i=0;
for( i=0; i < data_length; i++)
printf("%02X",data[i]);
printf("\n");
if (m3ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M3AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof(
m3ap_message_decoded_callback))
|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m3ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M3AP, "Calling handler with instance %d\n",instance);
ret = (*m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return ret;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_handler.h
* \brief m2ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_OLD_HANDLERS_H_
#define M2AP_MCE_OLD_HANDLERS_H_
#include "m2ap_eNB_defs.h"
//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
//const uint8_t * const data, const uint32_t data_length);
int m3ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
#endif /* M2AP_MCE_HANDLERS_H_ */
+128
View File
@@ -0,0 +1,128 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "m3ap_ids.h"
#include <string.h>
void m3ap_id_manager_init(m3ap_id_manager *m)
{
int i;
memset(m, 0, sizeof(m3ap_id_manager));
for (i = 0; i < M3AP_MAX_IDS; i++)
m->ids[i].rnti = -1;
}
int m3ap_allocate_new_id(m3ap_id_manager *m)
{
int i;
for (i = 0; i < M3AP_MAX_IDS; i++)
if (m->ids[i].rnti == -1) {
m->ids[i].rnti = 0;
m->ids[i].id_source = -1;
m->ids[i].id_target = -1;
return i;
}
return -1;
}
void m3ap_release_id(m3ap_id_manager *m, int id)
{
m->ids[id].rnti = -1;
}
int m3ap_find_id(m3ap_id_manager *m, int id_source, int id_target)
{
int i;
for (i = 0; i < M3AP_MAX_IDS; i++)
if (m->ids[i].rnti != -1 &&
m->ids[i].id_source == id_source &&
m->ids[i].id_target == id_target)
return i;
return -1;
}
int m3ap_find_id_from_id_source(m3ap_id_manager *m, int id_source)
{
int i;
for (i = 0; i < M3AP_MAX_IDS; i++)
if (m->ids[i].rnti != -1 &&
m->ids[i].id_source == id_source)
return i;
return -1;
}
int m3ap_find_id_from_rnti(m3ap_id_manager *m, int rnti)
{
int i;
for (i = 0; i < M3AP_MAX_IDS; i++)
if (m->ids[i].rnti == rnti)
return i;
return -1;
}
void m3ap_set_ids(m3ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target)
{
m->ids[ue_id].rnti = rnti;
m->ids[ue_id].id_source = id_source;
m->ids[ue_id].id_target = id_target;
}
/* real type of target is m3ap_eNB_data_t * */
void m3ap_id_set_target(m3ap_id_manager *m, int ue_id, void *target)
{
m->ids[ue_id].target = target;
}
void m3ap_id_set_state(m3ap_id_manager *m, int ue_id, m3id_state_t state)
{
m->ids[ue_id].state = state;
}
void m3ap_set_reloc_prep_timer(m3ap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].t_reloc_prep_start = time;
}
void m3ap_set_reloc_overall_timer(m3ap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].tm3_reloc_overall_start = time;
}
int m3ap_id_get_id_source(m3ap_id_manager *m, int ue_id)
{
return m->ids[ue_id].id_source;
}
int m3ap_id_get_id_target(m3ap_id_manager *m, int ue_id)
{
return m->ids[ue_id].id_target;
}
int m3ap_id_get_rnti(m3ap_id_manager *m, int ue_id)
{
return m->ids[ue_id].rnti;
}
void *m3ap_id_get_target(m3ap_id_manager *m, int ue_id)
{
return m->ids[ue_id].target;
}
+80
View File
@@ -0,0 +1,80 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef M3AP_IDS_H_
#define M3AP_IDS_H_
#include <stdint.h>
/* maximum number of simultaneous handovers, do not set too high */
#define M3AP_MAX_IDS 16
/*
* state:
* - when starting handover in source, UE is in state M3ID_STATE_SOURCE_PREPARE
* - after receiving HO_ack in source, UE is in state M3ID_STATE_SOURCE_OVERALL
* - in target, UE is in state X2ID_STATE_TARGET
* The state is used to check timers.
*/
typedef enum {
M3ID_STATE_SOURCE_PREPARE,
M3ID_STATE_SOURCE_OVERALL,
M3ID_STATE_TARGET
} m3id_state_t;
typedef struct {
int rnti; /* -1 when free */
int id_source;
int id_target;
/* the target eNB. Real type is m3ap_eNB_data_t * */
void *target;
/* state: needed to check timers */
m3id_state_t state;
/* timers */
uint64_t t_reloc_prep_start;
uint64_t tm3_reloc_overall_start;
} m3ap_id;
typedef struct {
m3ap_id ids[M3AP_MAX_IDS];
} m3ap_id_manager;
void m3ap_id_manager_init(m3ap_id_manager *m);
int m3ap_allocate_new_id(m3ap_id_manager *m);
void m3ap_release_id(m3ap_id_manager *m, int id);
int m3ap_find_id(m3ap_id_manager *, int id_source, int id_target);
int m3ap_find_id_from_id_source(m3ap_id_manager *, int id_source);
int m3ap_find_id_from_rnti(m3ap_id_manager *, int rnti);
void m3ap_set_ids(m3ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
void m3ap_id_set_state(m3ap_id_manager *m, int ue_id, m3id_state_t state);
/* real type of target is m3ap_eNB_data_t * */
void m3ap_id_set_target(m3ap_id_manager *m, int ue_id, void *target);
void m3ap_set_reloc_prep_timer(m3ap_id_manager *m, int ue_id, uint64_t time);
void m3ap_set_reloc_overall_timer(m3ap_id_manager *m, int ue_id, uint64_t time);
int m3ap_id_get_id_source(m3ap_id_manager *m, int ue_id);
int m3ap_id_get_id_target(m3ap_id_manager *m, int ue_id);
int m3ap_id_get_rnti(m3ap_id_manager *m, int ue_id);
void *m3ap_id_get_target(m3ap_id_manager *m, int ue_id);
#endif /* M3AP_IDS_H_ */
+96
View File
@@ -0,0 +1,96 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_itti_messaging.c
* \brief m3ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include "intertask_interface.h"
#include "m3ap_itti_messaging.h"
void m3ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream)
{
MessageDef *message_p;
sctp_data_req_t *sctp_data_req;
message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_DATA_REQ);
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
sctp_data_req->assoc_id = assoc_id;
sctp_data_req->buffer = buffer;
sctp_data_req->buffer_length = buffer_length;
sctp_data_req->stream = stream;
//LOG_W(M3AP,"assoc_id %d, stream %d\n",assoc_id,stream);
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
void m3ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
{
MessageDef *message_p = NULL;
sctp_close_association_t *sctp_close_association_p = NULL;
message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_CLOSE_ASSOCIATION);
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
sctp_close_association_p->assoc_id = assoc_id;
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
void m3ap_MME_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream)
{
MessageDef *message_p;
sctp_data_req_t *sctp_data_req;
message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_DATA_REQ);
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
sctp_data_req->assoc_id = assoc_id;
sctp_data_req->buffer = buffer;
sctp_data_req->buffer_length = buffer_length;
sctp_data_req->stream = stream;
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
void m3ap_MME_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
{
MessageDef *message_p = NULL;
sctp_close_association_t *sctp_close_association_p = NULL;
message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_CLOSE_ASSOCIATION);
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
sctp_close_association_p->assoc_id = assoc_id;
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
+48
View File
@@ -0,0 +1,48 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_itti_messaging.h
* \brief m3ap tasks for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_MCE_ITTI_MESSAGING_H_
#define M3AP_MCE_ITTI_MESSAGING_H_
void m3ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream);
void m3ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id);
void m3ap_MME_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream);
void m3ap_MME_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id);
#endif /* M3AP_MCE_ITTI_MESSAGING_H_ */
+105
View File
@@ -0,0 +1,105 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "m3ap_timers.h"
#include "assertions.h"
#include "PHY/defs_common.h" /* TODO: try to not include this */
#include "m3ap_messages_types.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_ids.h"
#include "m3ap_MCE_management_procedures.h"
//#include "m3ap_eNB_generate_messages.h"
void m3ap_timers_init(m3ap_timers_t *t, int t_reloc_prep, int tm3_reloc_overall)
{
t->tti = 0;
t->t_reloc_prep = t_reloc_prep;
t->tm3_reloc_overall = tm3_reloc_overall;
}
void m3ap_check_timers(instance_t instance)
{
//m3ap_eNB_instance_t *instance_p;
//m3ap_timers_t *t;
//m3ap_id_manager *m;
//int i;
//m3ap_handover_cancel_cause_t cause;
//void *target;
//MessageDef *msg;
//int m2_ongoing;
//instance_p = m3ap_eNB_get_instance(instance);
//DevAssert(instance_p != NULL);
//t = &instance_p->timers;
//m = &instance_p->id_manager;
///* increment subframe count */
//t->tti++;
//m2_ongoing = 0;
//for (i = 0; i < M3AP_MAX_IDS; i++) {
// if (m->ids[i].rnti == -1) continue;
// m2_ongoing++;
// if (m->ids[i].state == M2ID_STATE_SOURCE_PREPARE &&
// t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) {
// LOG_I(M3AP, "M2 timeout reloc prep\n");
// /* t_reloc_prep timed out */
// cause = M3AP_T_RELOC_PREP_TIMEOUT;
// goto timeout;
// }
// if (m->ids[i].state == M2ID_STATE_SOURCE_OVERALL &&
// t->tti > m->ids[i].tm2_reloc_overall_start + t->tm2_reloc_overall) {
// LOG_I(M3AP, "M2 timeout reloc overall\n");
// /* tm2_reloc_overall timed out */
// cause = M3AP_TM2_RELOC_OVERALL_TIMEOUT;
// goto timeout;
// }
// /* no timeout -> check next UE */
// continue;
// timeout:
// /* inform target about timeout */
// target = m3ap_id_get_target(m, i);
// m3ap_eNB_generate_m2_handover_cancel(instance_p, target, i, cause);
// /* inform RRC of cancellation */
// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_CANCEL);
// M3AP_HANDOVER_CANCEL(msg).rnti = m3ap_id_get_rnti(m, i);
// M3AP_HANDOVER_CANCEL(msg).cause = cause;
// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
// /* remove UE from M3AP */
// m3ap_release_id(m, i);
//}
//if (m2_ongoing && t->tti % 1000 == 0)
// LOG_I(M3AP, "M2 has %d process ongoing\n", m2_ongoing);
}
uint64_t m3ap_timer_get_tti(m3ap_timers_t *t)
{
return t->tti;
}
+45
View File
@@ -0,0 +1,45 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef M3AP_TIMERS_H_
#define M3AP_TIMERS_H_
#include <stdint.h>
#include "platform_types.h"
typedef struct {
/* incremented every TTI (every millisecond when in realtime).
* Used to check timers.
* 64 bits gives us more than 500 million years of (realtime) processing.
* It should be enough.
*/
uint64_t tti;
/* timer values (unit: TTI, ie. millisecond when in realtime) */
int t_reloc_prep;
int tm3_reloc_overall;
} m3ap_timers_t;
void m3ap_timers_init(m3ap_timers_t *t, int t_reloc_prep, int tm3_reloc_overall);
void m3ap_check_timers(instance_t instance);
uint64_t m3ap_timer_get_tti(m3ap_timers_t *t);
#endif /* M3AP_TIMERS_H_ */
+174
View File
@@ -0,0 +1,174 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file openair2/ENB_APP/enb_paramdef_mce.h
* \brief definition of configuration parameters for MME modules
* \author Javier MORGADE
* \date 2019
* \version 0.1
* \company VICOMTECH Spain
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#include "common/config/config_paramdesc.h"
#include "RRC_paramsvalues.h"
#define ENB_CONFIG_STRING_MME_PARAMETERS "mme_parameters"
//#define ENB_CONFIG_STRING_SCHEDULING_INFO_BR "scheduling_info_br"
//#define ENB_CONFIG_STRING_RSRP_RANGE_LIST "rsrp_range_list"
//#define ENB_CONFIG_STRING_PRACH_CONFIG_COMMON_V1310 "prach_ConfigCommon_v1310"
//#define ENB_CONFIG_STRING_MPDCCH_START_SF_CSS_RA_R13 "mpdcch_startSF_CSS_RA_r13"
//#define ENB_CONFIG_STRING_MPDCCH_START_SF_CSS_RA_R13_VAL "mpdcch_startSF_CSS_RA_r13_val"
//#define ENB_CONFIG_STRING_PRACH_HOPPING_OFFSET_R13 "prach_HoppingOffset_r13"
//#define ENB_CONFIG_STRING_SCHEDULING_INFO_SIB1_BR_R13 "schedulingInfoSIB1_BR_r13"
//#define ENB_CONFIG_STRING_CELL_SELECTION_INFO_CE_R13 "cellSelectionInfoCE_r13"
//#define ENB_CONFIG_STRING_Q_RX_LEV_MIN_CE_R13 "q_RxLevMinCE_r13"
//#define ENB_CONFIG_STRING_BANDWIDTH_REDUCED_ACCESS_RELATED_INFO_R13 "bandwidthReducedAccessRelatedInfo_r13"
//#define ENB_CONFIG_STRING_SI_WINDOW_LENGTH_BR_R13 "si_WindowLength_BR_r13"
//#define ENB_CONFIG_STRING_SI_REPETITION_PATTERN_R13 "si_RepetitionPattern_r13"
//#define ENB_CONFIG_STRING_FDD_DOWNLINK_OR_TDD_SUBFRAME_BITMAP_BR_R13 "fdd_DownlinkOrTddSubframeBitmapBR_r13"
//#define ENB_CONFIG_STRING_FDD_DOWNLINK_OR_TDD_SUBFRAME_BITMAP_BR_VAL_R13 "fdd_DownlinkOrTddSubframeBitmapBR_val_r13"
//#define ENB_CONFIG_STRING_START_SYMBOL_BR_R13 "startSymbolBR_r13"
//#define ENB_CONFIG_STRING_SI_HOPPING_CONFIG_COMMON_R13 "si_HoppingConfigCommon_r13"
//#define ENB_CONFIG_STRING_SI_VALIDITY_TIME_R13 "si_ValidityTime_r13"
//#define ENB_CONFIG_STRING_FREQ_HOPPING_PARAMETERS_DL_R13 "freqHoppingParametersDL_r13"
//#define ENB_CONFIG_STRING_MPDCCH_PDSCH_HOPPING_NB_R13 "mpdcch_pdsch_HoppingNB_r13"
//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_A_R13 "interval_DLHoppingConfigCommonModeA_r13"
//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_A_R13_VAL "interval_DLHoppingConfigCommonModeA_r13_val"
//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_B_R13 "interval_DLHoppingConfigCommonModeB_r13"
//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_B_R13_VAL "interval_DLHoppingConfigCommonModeB_r13_val"
//#define ENB_CONFIG_STRING_MPDCCH_PDSCH_HOPPING_OFFSET_R13 "mpdcch_pdsch_HoppingOffset_r13"
//#define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13 "preamble_TransMax_ce_r13"
//#define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13_VAL "preamble_TransMax_ce_r13_val"
//#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13"
//#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13"
//#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13"
//#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13"
//#define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310"
//#define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI"
//#define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13"
//#define ENB_CONFIG_STRING_LAST_PREAMBLE_R13 "lastPreamble_r13"
//#define ENB_CONFIG_STRING_RA_RESPONSE_WINDOW_SIZE_R13 "ra_ResponseWindowSize_r13"
//#define ENB_CONFIG_STRING_MAC_CONTENTION_RESOLUTION_TIMER_R13 "mac_ContentionResolutionTimer_r13"
//#define ENB_CONFIG_STRING_RAR_HOPPING_CONFIG_R13 "rar_HoppingConfig_r13"
//#define ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13 "rach_CE_LevelInfoList_r13"
//#define ENB_CONFIG_STRING_PRACH_CONFIG_INDEX_BR "prach_config_index_br"
//#define ENB_CONFIG_STRING_PRACH_FREQ_OFFSET_BR "prach_freq_offset_br"
//#define ENB_CONFIG_STRING_PRACH_STARTING_SUBFRAME_R13 "prach_StartingSubframe_r13"
//#define ENB_CONFIG_STRING_MAX_NUM_PER_PREAMBLE_ATTEMPT_CE_R13 "maxNumPreambleAttemptCE_r13"
//#define ENB_CONFIG_STRING_NUM_REPETITION_PER_PREAMBLE_ATTEMPT_R13 "numRepetitionPerPreambleAttempt_r13"
//#define ENB_CONFIG_STRING_MPDCCH_NUM_REPETITION_RA_R13 "mpdcch_NumRepetition_RA_r13"
//#define ENB_CONFIG_STRING_PRACH_HOPPING_CONFIG_R13 "prach_HoppingConfig_r13"
//#define ENB_CONFIG_SRING_MAX_AVAILABLE_NARROW_BAND "max_available_narrow_band"
//#define ENB_CONFIG_STRING_PRACH_PARAMETERS_CE_R13 "prach_parameters_ce_r13"
//#define ENB_CONFIG_STRING_PUCCH_INFO_VALUE "pucch_info_value"
//#define ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13 "n1PUCCH_AN_InfoList_r13"
//#define ENB_CONFIG_STRING_PCCH_CONFIG_V1310 "pcch_config_v1310"
//#define ENB_CONFIG_STRING_PAGING_NARROWBANDS_R13 "paging_narrowbands_r13"
//#define ENB_CONFIG_STRING_MPDCCH_NUMREPETITION_PAGING_R13 "mpdcch_numrepetition_paging_r13"
//#define ENB_CONFIG_STRING_NB_V1310 "nb_v1310"
//#define ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13 "sib2_freq_hoppingParameters_r13"
typedef struct ccparams_MME_s {
/// indicator that eMTC is configured for this cell
int32_t MME_configured;
// /// the SIB2 parameters for eMTC SIB2
// ccparams_lte_t ccparams;
// int si_Narrowband_r13;
// int si_TBS_r13;
// int systemInfoValueTagSi_r13;
// int firstPreamble_r13;
// int lastPreamble_r13;
// int ra_ResponseWindowSize_r13;
// int mac_ContentionResolutionTimer_r13;
// int rar_HoppingConfig_r13;
// int rsrp_range_br;
// int prach_config_index_br;
// int prach_freq_offset_br;
// int prach_StartingSubframe_r13;
// int maxNumPreambleAttemptCE_r13;
// int numRepetitionPerPreambleAttempt_r13;
// int mpdcch_NumRepetition_RA_r13;
// int prach_HoppingConfig_r13;
// int *maxavailablenarrowband;
// int pucch_info_value;
// int paging_narrowbands_r13;
// int mpdcch_numrepetition_paging_r13;
// int nb_v1310;
// char *pucch_NumRepetitionCE_Msg4_Level0_r13;
// char *pucch_NumRepetitionCE_Msg4_Level1_r13;
// char *pucch_NumRepetitionCE_Msg4_Level2_r13;
// char *pucch_NumRepetitionCE_Msg4_Level3_r13;
// int sib2_mpdcch_pdsch_hoppingNB_r13;
// char *sib2_interval_DLHoppingConfigCommonModeA_r13;
// int sib2_interval_DLHoppingConfigCommonModeA_r13_val;
// char *sib2_interval_DLHoppingConfigCommonModeB_r13;
// int sib2_interval_DLHoppingConfigCommonModeB_r13_val;
// char *sib2_interval_ULHoppingConfigCommonModeA_r13;
// int sib2_interval_ULHoppingConfigCommonModeA_r13_val;
// char *sib2_interval_ULHoppingConfigCommonModeB_r13;
// int sib2_interval_ULHoppingConfigCommonModeB_r13_val;
// int sib2_mpdcch_pdsch_hoppingOffset_r13;
// int pusch_HoppingOffset_v1310;
// int hyperSFN_r13;
// int eDRX_Allowed_r13;
// int q_RxLevMinCE_r13;
// int q_QualMinRSRQ_CE_r13;
// char *si_WindowLength_BR_r13;
// char *si_RepetitionPattern_r13;
// int startSymbolBR_r13;
// char *si_HoppingConfigCommon_r13;
// char *si_ValidityTime_r13;
// char *mpdcch_pdsch_HoppingNB_r13;
// int interval_DLHoppingConfigCommonModeA_r13_val;
// int interval_DLHoppingConfigCommonModeB_r13_val;
// int mpdcch_pdsch_HoppingOffset_r13;
// char *preambleTransMax_CE_r13;
// int prach_HoppingOffset_r13;
// int schedulingInfoSIB1_BR_r13;
// int64_t fdd_DownlinkOrTddSubframeBitmapBR_val_r13;
// char *cellSelectionInfoCE_r13;
// char *bandwidthReducedAccessRelatedInfo_r13;
// char *fdd_DownlinkOrTddSubframeBitmapBR_r13;
// char *fdd_UplinkSubframeBitmapBR_r13;
// char *freqHoppingParametersDL_r13;
// char *interval_DLHoppingConfigCommonModeA_r13;
// char *interval_DLHoppingConfigCommonModeB_r13;
// char *prach_ConfigCommon_v1310;
// char *mpdcch_startSF_CSS_RA_r13;
// char *mpdcch_startSF_CSS_RA_r13_val;
// char *pdsch_maxNumRepetitionCEmodeA_r13;
// char *pdsch_maxNumRepetitionCEmodeB_r13;
// char *pusch_maxNumRepetitionCEmodeA_r13;
// char *pusch_maxNumRepetitionCEmodeB_r13;
} ccparams_MME_t;
#define MMEPARAMS_DESC(MMEconfig) { \
{"MME_configured", NULL, 0, iptr:&MMEconfig->MME_configured, defintval:0, TYPE_UINT, 0} \
}
#define MMEPARAMS_CHECK { \
{ .s5= {NULL }} \
}
+580
View File
@@ -0,0 +1,580 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
mme_app.c
-------------------
AUTHOR : Javier Morgade
COMPANY : VICOMTECH Spain
EMAIL : javier.morgade@ieee.org
*/
#include <string.h>
#include <stdio.h>
#include "mme_app.h"
#include "mme_config.h"
#include "assertions.h"
#include "common/ran_context.h"
#include "targets/RT/USER/lte-softmodem.h"
#include "common/utils/LOG/log.h"
# include "intertask_interface.h"
# include "s1ap_eNB.h"
# include "sctp_eNB_task.h"
# include "gtpv1u_eNB_task.h"
# include "flexran_agent.h"
# include "x2ap_eNB.h"
# include "x2ap_messages_types.h"
# include "m2ap_eNB.h"
# include "m3ap_MME.h"
# include "m2ap_messages_types.h"
//# include "m3ap_eNB.h"
# include "m3ap_messages_types.h"
# define X2AP_ENB_REGISTER_RETRY_DELAY 10
#include "openair1/PHY/INIT/phy_init.h"
extern unsigned char NB_MCE_INST;
extern RAN_CONTEXT_t RC;
# define MCE_REGISTER_RETRY_DELAY 10
#include "targets/RT/USER/lte-softmodem.h"
/*------------------------------------------------------------------------------*/
//static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, uint32_t mce_id_end) {
// uint32_t mce_id;
// MessageDef *msg_p;
// uint32_t register_mce_pending = 0;
//
// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
// {
// // M3AP registration
// /* note: there is an implicit relationship between the data structure and the message name */
// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_REGISTER_MCE_REQ);
// //RCconfig_S1(msg_p, mce_id);
//
// //if (mce_id == 0)
// //RCconfig_gtpu();
//
// //LOG_I(MME_APP,"default drx %d\n",((M3AP_REGISTER_MCE_REQ(msg_p)).default_drx));
//
// LOG_I(ENB_APP,"[MCE %d] MCE_app_register via M3AP for instance %d\n", mce_id, ENB_MODULE_ID_TO_INSTANCE(mce_id));
// itti_send_msg_to_task (TASK_M3AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
//
// //if (NODE_IS_DU(node_type)) { // F1AP registration
// // // configure F1AP here for F1C
// // LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
// // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ);
// // RCconfig_DU_F1(msg_p, enb_id);
//
// // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
// // itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
// // // configure GTPu here for F1U
// //}
// //else { // S1AP registration
// // /* note: there is an implicit relationship between the data structure and the message name */
// // msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
// // RCconfig_S1(msg_p, enb_id);
//
// // if (enb_id == 0) RCconfig_gtpu();
//
// // LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx));
//
// // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
// // itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
// //}
//
// register_mce_pending++;
// }
// }
//
// return register_mce_pending;
//}
/*------------------------------------------------------------------------------*/
//static uint32_t MCE_app_register_x2(uint32_t mce_id_start, uint32_t mce_id_end) {
// uint32_t mce_id;
// MessageDef *msg_p;
// uint32_t register_mce_m2_pending = 0;
//
// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
// {
// msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ);
// RCconfig_X2(msg_p, mce_id);
// itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
// register_mce_x2_pending++;
// }
// }
//
// return register_mce_x2_pending;
//}
/*------------------------------------------------------------------------------*/
//static uint32_t MCE_app_register_m2(uint32_t mce_id_start, uint32_t mce_id_end) {
// uint32_t mce_id;
// MessageDef *msg_p;
// uint32_t register_mce_m2_pending = 0;
//
// LOG_W(MME_APP,"Register ...");
// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) {
// {
// // LOG_W(MME_APP,"Register commes inside ...\n");
// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_REGISTER_MCE_REQ);
// //RCconfig_M2_MCE(msg_p, mce_id);
// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p);
// // LOG_W(MME_APP,"Register sent ...\n");
// register_mce_m2_pending++;
// }
// }
//
// return register_mce_m2_pending;
//}
//
//
//
static uint32_t MME_app_handle_m3ap_setup_req(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_SETUP_RESP);
itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
static uint32_t MME_app_handle_m3ap_session_start_resp(instance_t instance){
return 0;
}
//
//static uint32_t MME_app_handle_m3ap_session_stop_resp(instance_t instance){
//
//
// return 0;
//}
//
//static uint32_t MCE_app_send_m2ap_mbms_scheduling_information(instance_t instance){
//
// uint32_t mce_id=0;
// MessageDef *msg_p;
// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_MBMS_SCHEDULING_INFORMATION);
// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
//
// return 0;
//}
//
static uint32_t MME_app_send_m3ap_session_start_req(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_START_REQ);
itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
//static uint32_t MME_app_send_m3ap_session_stop_req(instance_t instance){
//
// //uint32_t mce_id=0;
// MessageDef *msg_p;
// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_STOP_REQ);
// itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
//
// return 0;
//}
static uint32_t MME_app_send_m3ap_session_update_req(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_UPDATE_REQ);
itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
/*------------------------------------------------------------------------------*/
void *MME_app_task(void *args_p) {
//uint32_t mce_nb = RC.nb_inst;
//uint32_t mce_id_start = 0;
//uint32_t mce_id_end = mce_id_start + mce_nb;
//uint32_t register_mce_pending=0;
//uint32_t registered_mce=0;
//long mce_register_retry_timer_id;
//uint32_t m2_register_mce_pending = 0;
// uint32_t x2_registered_mce = 0;
// long x2_mce_register_retry_timer_id;
// uint32_t m2_register_mce_pending = 0;
// uint32_t m2_registered_mce = 0;
// long m2_mce_register_retry_timer_id;
long m3_mme_register_session_start_timer_id;
MessageDef *msg_p = NULL;
instance_t instance;
int result;
/* for no gcc warnings */
(void)instance;
itti_mark_task_ready (TASK_MME_APP);
/* Try to register each MCE */
// This assumes that node_type of all RRC instances is the same
if (EPC_MODE_ENABLED) {
//register_mce_pending = MCE_app_register(RC.rrc[0]->node_type, mce_id_start, mce_id_end);
}
/* Try to register each MCE with each other */
// if (is_x2ap_enabled() && !NODE_IS_DU(RC.rrc[0]->node_type)) {
// x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end);
// }
if ( is_m3ap_MME_enabled() ){
RCconfig_MME();
}
// /* Try to register each MCE with MCE each other */
//if (is_m3ap_MME_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) {
//m2_register_mce_pending = MCE_app_register_m2 (mce_id_start, mce_id_end);
//}
do {
// Wait for a message
itti_receive_msg (TASK_MME_APP, &msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
LOG_W(MME_APP, " *** Exiting MME_APP thread\n");
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_I(MME_APP, "MME_APP Received %s\n", ITTI_MSG_NAME(msg_p));
break;
case SOFT_RESTART_MESSAGE:
//handle_reconfiguration(instance);
break;
case M3AP_REGISTER_MCE_CNF: //M3AP_REGISTER_MCE_CNF debería
//AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n");
// if (EPC_MODE_ENABLED) {
// LOG_I(MME_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
// M3AP_REGISTER_MCE_CNF(msg_p).nb_mme);
// DevAssert(register_mce_pending > 0);
// register_mce_pending--;
// /* Check if at least MCE is registered with one MME */
// if (M3AP_REGISTER_MCE_CNF(msg_p).nb_mme > 0) {
// registered_mce++;
// }
// /* Check if all register MCE requests have been processed */
// if (register_mce_pending == 0) {
// if (registered_mce == mce_nb) {
// /* If all MCE are registered, start L2L1 task */
// // MessageDef *msg_init_p;
// // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
// // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
// } else {
// LOG_W(MME_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n",
// mce_nb - registered_mce, MCE_REGISTER_RETRY_DELAY);
// /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */
// if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MME_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
// NULL, &mce_register_retry_timer_id) < 0) {
// LOG_E(MME_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n");
// sleep(MCE_REGISTER_RETRY_DELAY);
// /* Restart the registration process */
// registered_mce = 0;
// register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end);
// }
// }
// }
// } /* if (EPC_MODE_ENABLED) */
break;
// case M3AP_SETUP_RESP:
// //AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/MCE\n");
// //LOG_I(MME_APP, "Received %s: associated ngran_MCE_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
// //F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
//
// //handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
// handle_m3ap_setup_resp(&M3AP_SETUP_RESP(msg_p));
// DevAssert(register_mce_pending > 0);
// register_mce_pending--;
// /* Check if at least MCE is registered with one MME */
// //if (M3AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) {
// // registered_enb++;
// //}
// /* Check if all register MCE requests have been processed */
// if (register_mce_pending == 0) {
// if (registered_mce == mce_nb) {
// /* If all MCE cells are registered, start L2L1 task */
// MessageDef *msg_init_p;
// //msg_init_p = itti_alloc_new_message (TASK_MME_APP, INITIALIZE_MESSAGE);
// //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
// } else {
// LOG_W(MME_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n",
// mce_nb - registered_mce, MCE_REGISTER_RETRY_DELAY);
// /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */
// if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MME_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
// NULL, &mce_register_retry_timer_id) < 0) {
// LOG_E(ENB_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n");
// sleep(MCE_REGISTER_RETRY_DELAY);
// /* Restart the registration process */
// registered_mce = 0;
// register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end);//, enb_properties_p);
// }
// }
// }
// break;
case M3AP_DEREGISTERED_MCE_IND: //M3AP_DEREGISTERED_MCE_IND debería
if (EPC_MODE_ENABLED) {
LOG_W(MME_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme);
/* TODO handle recovering of registration */
}
break;
case TIMER_HAS_EXPIRED:
//if (EPC_MODE_ENABLED) {
// LOG_I(MME_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
// if (TIMER_HAS_EXPIRED (msg_p).timer_id == mce_register_retry_timer_id) {
// /* Restart the registration process */
// registered_mce = 0;
// //register_mce_pending = MCE_app_register (RC.rrc[0]->node_type, mce_id_start, mce_id_end);
// }
// //if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_mce_register_retry_timer_id) {
// // /* Restart the registration process */
// // x2_registered_mce = 0;
// // x2_register_mce_pending = MCE_app_register_x2 (mce_id_start, mce_id_end);
// //}
//} /* if (EPC_MODE_ENABLED) */
if(TIMER_HAS_EXPIRED(msg_p).timer_id == m3_mme_register_session_start_timer_id){
MME_app_send_m3ap_session_start_req(0);
}
break;
// case X2AP_DEREGISTERED_ENB_IND:
// LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
// X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2);
// /* TODO handle recovering of registration */
// break;
// case X2AP_REGISTER_ENB_CNF:
// LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
// X2AP_REGISTER_ENB_CNF(msg_p).nb_x2);
// DevAssert(x2_register_enb_pending > 0);
// x2_register_enb_pending--;
// /* Check if at least MCE is registered with one target MCE */
// if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) {
// x2_registered_enb++;
// }
// /* Check if all register MCE requests have been processed */
// if (x2_register_enb_pending == 0) {
// if (x2_registered_enb == enb_nb) {
// /* If all MCE are registered, start RRC HO task */
// } else {
// uint32_t x2_not_associated = enb_nb - x2_registered_enb;
// LOG_W(ENB_APP, " %d MCE %s not associated with the target\n",
// x2_not_associated, x2_not_associated > 1 ? "are" : "is");
// // timer to retry
// /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */
// if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
// INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
// &x2_enb_register_retry_timer_id) < 0) {
// LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n");
// sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
// /* Restart the registration process */
// x2_registered_enb = 0;
// x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end);
// }
// }
// }
// break;
// case M2AP_DEREGISTERED_ENB_IND:
// LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
// M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2);
// /* TODO handle recovering of registration */
// break;
// case M2AP_REGISTER_ENB_CNF:
// LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p),
// M2AP_REGISTER_ENB_CNF(msg_p).nb_m2);
// DevAssert(m2_register_enb_pending > 0);
// m2_register_enb_pending--;
// /* Check if at least MCE is registered with one target MCE */
// if (M2AP_REGISTER_ENB_CNF(msg_p).nb_m2 > 0) {
// m2_registered_enb++;
// }
// /* Check if all register MCE requests have been processed */
// if (m2_register_enb_pending == 0) {
// if (m2_registered_enb == enb_nb) {
// /* If all MCE are registered, start RRC HO task */
// } else {
// uint32_t m2_not_associated = enb_nb - m2_registered_enb;
// LOG_W(ENB_APP, " %d MCE %s not associated with the target\n",
// m2_not_associated, m2_not_associated > 1 ? "are" : "is");
// // timer to retry
// /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */
// //if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
// // INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
// // &x2_enb_register_retry_timer_id) < 0) {
// // LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n");
// // sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
// // /* Restart the registration process */
// // x2_registered_enb = 0;
// // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end);
// //}
// }
// }
// break;
case M3AP_RESET:
LOG_I(MME_APP,"Received M3AP_RESET message %s\n",ITTI_MSG_NAME(msg_p));
break;
case M3AP_SETUP_REQ:
LOG_I(MME_APP,"Received M3AP_REQ message %s\n",ITTI_MSG_NAME(msg_p));
MME_app_handle_m3ap_setup_req(0);
if(timer_setup(1,0,TASK_MME_APP,INSTANCE_DEFAULT,TIMER_ONE_SHOT,NULL,&m3_mme_register_session_start_timer_id)<0){
}
//MME_app_send_m3ap_session_start_req(0);
break;
case M3AP_MBMS_SESSION_START_RESP:
LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_START_RESP message %s\n",ITTI_MSG_NAME(msg_p));
MME_app_handle_m3ap_session_start_resp(0);
//MME_app_send_m3ap_session_stop_req(0);
break;
case M3AP_MBMS_SESSION_STOP_RESP:
LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_STOP_RESP message %s\n",ITTI_MSG_NAME(msg_p));
MME_app_send_m3ap_session_update_req(0);
break;
case M3AP_MBMS_SESSION_UPDATE_RESP:
LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_UPDATE_RESP message %s\n",ITTI_MSG_NAME(msg_p));
// trigger something new here !!!!!!
break;
case M3AP_MBMS_SESSION_UPDATE_FAILURE:
LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_UPDATE_FAILURE message %s\n",ITTI_MSG_NAME(msg_p));
break;
case M3AP_MCE_CONFIGURATION_UPDATE:
LOG_I(MME_APP,"Received M3AP_MCE_CONFIGURATION_UPDATE message %s\n",ITTI_MSG_NAME(msg_p));
break;
default:
LOG_E(MME_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while (1);
return NULL;
}
//void handle_reconfiguration(module_id_t mod_id) {
// struct timespec start, end;
// clock_gettime(CLOCK_MONOTONIC, &start);
// flexran_agent_info_t *flexran = RC.flexran[mod_id];
// LOG_I(ENB_APP, "lte-softmodem soft-restart requested\n");
//
// if (ENB_WAIT == flexran->node_ctrl_state) {
// /* this is already waiting, just release */
// pthread_mutex_lock(&flexran->mutex_node_ctrl);
// flexran->node_ctrl_state = ENB_NORMAL_OPERATION;
// pthread_mutex_unlock(&flexran->mutex_node_ctrl);
// pthread_cond_signal(&flexran->cond_node_ctrl);
// return;
// }
//
// if (stop_L1L2(mod_id) < 0) {
// LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n");
// return;
// }
//
// /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not
// * executed by the FlexRAN thread */
// if (ENB_MAKE_WAIT == flexran->node_ctrl_state) {
// LOG_I(ENB_APP, " * MCE %d: Waiting for FlexRAN RTController command *\n", mod_id);
// pthread_mutex_lock(&flexran->mutex_node_ctrl);
// flexran->node_ctrl_state = ENB_WAIT;
//
// while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state)
// pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl);
//
// pthread_mutex_unlock(&flexran->mutex_node_ctrl);
// }
//
// if (restart_L1L2(mod_id) < 0) {
// LOG_E(ENB_APP, "can not restart, killing lte-softmodem\n");
// exit_fun("can not restart L1L2, killing lte-softmodem");
// return;
// }
//
// clock_gettime(CLOCK_MONOTONIC, &end);
// end.tv_sec -= start.tv_sec;
//
// if (end.tv_nsec >= start.tv_nsec) {
// end.tv_nsec -= start.tv_nsec;
// } else {
// end.tv_sec -= 1;
// end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000;
// }
//
// LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000);
//}
+41
View File
@@ -0,0 +1,41 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
mme_app.h
-------------------
AUTHOR : Javier Morgade
COMPANY : VICOMTECH Spain
EMAIL : javier.morgade@ieee.org
*/
#ifndef MME_APP_H_
#define MME_APP_H_
#include <stdint.h>
#include "platform_types.h"
void *MME_app_task(void *args_p);
//void handle_reconfiguration(module_id_t mod_id);
#endif /* MME_APP_H_ */
+111
View File
@@ -0,0 +1,111 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
mme_config.c
-------------------
AUTHOR : Javier Morgade
COMPANY : VICOMTECH, Spain
EMAIL : javier.morgade@ieee.org
*/
#include <string.h>
#include <inttypes.h>
#include "common/utils/LOG/log.h"
#include "assertions.h"
#include "mme_config.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_externs.h"
#include "intertask_interface.h"
#include "s1ap_eNB.h"
#include "sctp_eNB_task.h"
#include "common/ran_context.h"
#include "sctp_default_values.h"
#include "LTE_SystemInformationBlockType2.h"
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "PHY/phy_extern.h"
#include "PHY/INIT/phy_init.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "nfapi_vnf.h"
#include "nfapi_pnf.h"
#include "L1_paramdef.h"
#include "MACRLC_paramdef.h"
#include "common/config/config_userapi.h"
#include "RRC_config_tools.h"
#include "enb_paramdef.h"
#include "proto_agent.h"
int RCconfig_MME(void ) {
//int num_enbs = 0;
//char *enb_interface_name_for_S1U = NULL;
char *mme_interface_name_for_m3_mce = NULL;
//char *enb_ipv4_address_for_S1U = NULL;
char *mme_ipv4_address_for_m3c = NULL;
//uint32_t enb_port_for_S1U = 0;
uint32_t mme_port_for_m3c = 0;
char *address = NULL;
char *cidr = NULL;
//char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
char mmepath[MAX_OPTNAME_SIZE*2 + 8];
//paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
//paramdef_t GTPUParams[] = GTPUPARAMS_DESC;
paramdef_t MMEParams[] = MME_NETPARAMS_DESC;
///* get number of active eNodeBs */
//config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
//num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
//AssertFatal (num_enbs >0,
// "Failed to parse config file no active eNodeBs in %s \n", ENB_CONFIG_STRING_ACTIVE_ENBS);
//sprintf(gtpupath,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,0,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
sprintf(mmepath,"%s.[%i].%s","MMEs",0,MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
//config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath);
config_get(MMEParams,sizeof(MMEParams)/sizeof(paramdef_t),mmepath);
//cidr = enb_ipv4_address_for_S1U;
cidr = mme_ipv4_address_for_m3c;
address = strtok(cidr, "/");
//LOG_W(MME_APP,"cidr %s\n",cidr);
//LOG_W(MME_APP,"address %s\n",address);
//LOG_W(MME_APP,"mme_interface_name_for_m3_mce %s\n",mme_interface_name_for_m3_mce);
//LOG_W(MME_APP,"mme_ipv4_address_for_m3c %s\n",mme_ipv4_address_for_m3c);
//LOG_W(MME_APP,"mme_port_for_m3c %d\n",mme_port_for_m3c);
if (address) {
MessageDef *message;
AssertFatal((message = itti_alloc_new_message(TASK_MME_APP, M3AP_MME_SCTP_REQ))!=NULL,"");
M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv6 = 0;
M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4 = 1;
strcpy( M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4_address, address);
LOG_I(MME_APP,"Configuring M3_C address : %s\n",address/*,M3AP_MME_SCTP_REQ(message).mme_m3_ip_address*/);
M3AP_MME_SCTP_REQ(message).mme_port_for_M3C = mme_port_for_m3c;
itti_send_msg_to_task (TASK_M3AP_MME, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(MCE_APP,"invalid address for M2AP\n");
return 0;
}
+52
View File
@@ -0,0 +1,52 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
mme_config.h
AUTHOR : Javier Morgade
COMPANY : Vicomtech, Spain
EMAIL : javier.morgade@ieee.org
*/
#ifndef MME_CONFIG_H_
#define MME_CONFIG_H_
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libconfig.h>
#include "commonDef.h"
#include "platform_types.h"
#include "platform_constants.h"
#include "PHY/impl_defs_lte.h"
#include "PHY/defs_eNB.h"
#include "s1ap_messages_types.h"
#include "f1ap_messages_types.h"
#include "LTE_SystemInformationBlockType2.h"
#include "rrc_messages_types.h"
#include "RRC/LTE/rrc_defs.h"
#include <intertask_interface.h>
#include "enb_paramdef.h"
int RCconfig_MME(void);
#endif /* MME_CONFIG_H_ */
/** @} */