From ac1347843f93011e0b3763fd7fd3e18d744e94d2 Mon Sep 17 00:00:00 2001
From: "javier.morgade@ieee.org" <javier.morgade@ieee.org>
Date: Sat, 14 Sep 2019 12:55:32 +0200
Subject: [PATCH] 	COMMON types updated: VCD,FAPI

	ACKNOWLEDGEMENT:
 	1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS"
 	2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu)

	Signed-off-by: javier.morgade@ieee.org <javier.morgade@ieee.org>
---
 common/ngran_types.h                          |   4 +-
 common/utils/LOG/log.c                        |   4 +
 common/utils/LOG/log.h                        |   4 +
 common/utils/LOG/vcd_signal_dumper.c          |   2 +
 common/utils/LOG/vcd_signal_dumper.h          |   2 +
 common/utils/T/T_defs.h                       |   2 +-
 common/utils/T/T_messages.txt                 |  94 +++++++++++++++
 common/utils/ocp_itti/all_msg.h               |   2 +
 common/utils/ocp_itti/intertask_interface.h   |  10 ++
 nfapi/open-nFAPI/nfapi/inc/nfapi.h            |   4 +
 .../nfapi/public_inc/nfapi_interface.h        |  23 ++++
 nfapi/open-nFAPI/nfapi/src/nfapi.c            | 109 ++++++++++++++++++
 nfapi/open-nFAPI/nfapi/src/nfapi_p5.c         |  26 ++++-
 13 files changed, 283 insertions(+), 3 deletions(-)

diff --git a/common/ngran_types.h b/common/ngran_types.h
index 224a85def5c..3dfa7aa01af 100644
--- a/common/ngran_types.h
+++ b/common/ngran_types.h
@@ -41,11 +41,13 @@ typedef enum {
   ngran_ng_eNB_CU = 4,
   ngran_gNB_CU    = 5,
   ngran_eNB_DU    = 6,
-  ngran_gNB_DU    = 7
+  ngran_gNB_DU    = 7,
+  ngran_eNB_MBMS_STA  = 8
 } ngran_node_t;
 
 #define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB    || (nOdE_TyPe) == ngran_ng_eNB    || (nOdE_TyPe) == ngran_gNB)
 #define NODE_IS_CU(nOdE_TyPe)         ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU)
 #define NODE_IS_DU(nOdE_TyPe)         ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU)
+#define NODE_IS_MBMS(nOdE_TyPe)       ((nOdE_TyPe) == ngran_eNB_MBMS_STA)
 
 #endif
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 857a83deab8..82de71538ea 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -404,6 +404,8 @@ int logInit (void) {
   register_log_component("eRAL","",RAL_ENB);
   register_log_component("mRAL","",RAL_UE);
   register_log_component("ENB_APP","log",ENB_APP);
+  register_log_component("MCE_APP","log",MCE_APP);
+  register_log_component("MME_APP","log",MME_APP);
   register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT);
   register_log_component("PROTO_AGENT","log",PROTO_AGENT);
   register_log_component("TMR","",TMR);
@@ -418,6 +420,8 @@ int logInit (void) {
   register_log_component("S1AP","",S1AP);
   register_log_component("F1AP","",F1AP);
   register_log_component("X2AP","",X2AP);
+  register_log_component("M2AP","",M2AP);
+  register_log_component("M3AP","",M3AP);
   register_log_component("SCTP","",SCTP);
   register_log_component("X2AP","",X2AP);
   register_log_component("LOADER","log",LOADER);
diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index be7db5470e4..2dc2474642f 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -213,6 +213,8 @@ typedef enum {
   RAL_ENB,
   RAL_UE,
   ENB_APP,
+  MCE_APP,
+  MME_APP,
   FLEXRAN_AGENT,
   TMR,
   USIM,
@@ -220,6 +222,8 @@ typedef enum {
   PROTO_AGENT,
   F1U,
   X2AP,
+  M2AP,
+  M3AP,
   LOADER,
   ASN,
   NFAPI_VNF,
diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c
index cc0296cb441..55d6c71d71a 100644
--- a/common/utils/LOG/vcd_signal_dumper.c
+++ b/common/utils/LOG/vcd_signal_dumper.c
@@ -452,6 +452,8 @@ const char* eurecomFunctionsNames[] = {
   "pdcp_fifo_read_buffer",
   "pdcp_fifo_flush",
   "pdcp_fifo_flush_buffer",
+  "pdcp_mbms_fifo_read",
+  "pdcp_mbms_fifo_read_buffer",
   /* RRC signals  */
   "rrc_rx_tx",
   "rrc_mac_config_req",
diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h
index 45525f85435..f8d3cd8387f 100644
--- a/common/utils/LOG/vcd_signal_dumper.h
+++ b/common/utils/LOG/vcd_signal_dumper.h
@@ -428,6 +428,8 @@ typedef enum {
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER,
 
   /* RRC signals  */
   VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index 3e4939ade08..8e93ffd71c8 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -41,7 +41,7 @@ typedef struct {
 } T_cache_t;
 
 /* number of VCD functions (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_FUNCTIONS (228)
+#define VCD_NUM_FUNCTIONS (230)
 
 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
 #define VCD_NUM_VARIABLES (177) 
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index 348d4837b7c..d73788934b0 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -359,6 +359,48 @@ ID = LEGACY_X2AP_TRACE
     GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_TRACE:LEGACY
     FORMAT = string,log
 
+ID = LEGACY_M2AP_INFO
+    DESC = M2AP legacy logs - info level
+    GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M2AP_ERROR
+    DESC = M2AP legacy logs - error level
+    GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M2AP_WARNING
+    DESC = M2AP legacy logs - warning level
+    GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M2AP_DEBUG
+    DESC = M2AP legacy logs - debug level
+    GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M2AP_TRACE
+    DESC = M2AP legacy logs - trace level
+    GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_M3AP_INFO
+    DESC = M3AP legacy logs - info level
+    GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M3AP_ERROR
+    DESC = M3AP legacy logs - error level
+    GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M3AP_WARNING
+    DESC = M3AP legacy logs - warning level
+    GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M3AP_DEBUG
+    DESC = M3AP legacy logs - debug level
+    GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_M3AP_TRACE
+    DESC = M3AP legacy logs - trace level
+    GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+
 ID = LEGACY_RRC_INFO
     DESC = RRC legacy logs - info level
     GROUP = ALL:LEGACY_RRC:LEGACY_GROUP_INFO:LEGACY
@@ -443,6 +485,48 @@ ID = LEGACY_ENB_APP_TRACE
     GROUP = ALL:LEGACY_ENB_APP:LEGACY_GROUP_TRACE:LEGACY
     FORMAT = string,log
 
+ID = LEGACY_MCE_APP_INFO
+    DESC = MCE_APP legacy logs - info level
+    GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MCE_APP_ERROR
+    DESC = MCE_APP legacy logs - error level
+    GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MCE_APP_WARNING
+    DESC = MCE_APP legacy logs - warning level
+    GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MCE_APP_DEBUG
+    DESC = MCE_APP legacy logs - debug level
+    GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MCE_APP_TRACE
+    DESC = MCE_APP legacy logs - trace level
+    GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_MME_APP_INFO
+    DESC = MME_APP legacy logs - info level
+    GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MME_APP_ERROR
+    DESC = MME_APP legacy logs - error level
+    GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MME_APP_WARNING
+    DESC = MME_APP legacy logs - warning level
+    GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MME_APP_DEBUG
+    DESC = MME_APP legacy logs - debug level
+    GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_MME_APP_TRACE
+    DESC = MME_APP legacy logs - trace level
+    GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+
 ID = LEGACY_FLEXRAN_AGENT_INFO
     DESC = FLEXRAN_AGENT legacy logs - info level
     GROUP = ALL:LEGACY_FLEXRAN_AGENT:LEGACY_GROUP_INFO:LEGACY
@@ -2893,6 +2977,16 @@ ID = VCD_FUNCTION_PDCP_FIFO_FLUSH_BUFFER
     GROUP = ALL:VCD:ENB:VCD_FUNCTION
     FORMAT = int,value
     VCD_NAME = pdcp_fifo_flush_buffer
+ID = VCD_FUNCTION_PDCP_MBMS_FIFO_READ
+    DESC = VCD function PDCP_MBMS_FIFO_READ
+    GROUP = ALL:VCD:ENB:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = pdcp_mbms_fifo_read
+ID = VCD_FUNCTION_PDCP_MBMS_FIFO_READ_BUFFER
+    DESC = VCD function PDCP_MBMS_FIFO_READ_BUFFER
+    GROUP = ALL:VCD:ENB:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = pdcp_mbms_fifo_read_buffer
 ID = VCD_FUNCTION_RRC_RX_TX
     DESC = VCD function RRC_RX_TX
     GROUP = ALL:VCD:ENB:VCD_FUNCTION
diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h
index bbbe576e1bf..a2add514e1e 100644
--- a/common/utils/ocp_itti/all_msg.h
+++ b/common/utils/ocp_itti/all_msg.h
@@ -9,6 +9,8 @@
 #endif
 #include "openair2/COMMON/s1ap_messages_def.h"
 #include "openair2/COMMON/x2ap_messages_def.h"
+#include "openair2/COMMON/m2ap_messages_def.h"
+#include "openair2/COMMON/m3ap_messages_def.h"
 #include "openair2/COMMON/sctp_messages_def.h"
 #include "openair2/COMMON/udp_messages_def.h"
 #include "openair2/COMMON/gtpv1_u_messages_def.h"
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 956d90072dd..8a313dba819 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -206,6 +206,8 @@ typedef struct IttiMsgText_s {
 #endif
 #include <openair2/COMMON/s1ap_messages_types.h>
 #include <openair2/COMMON/x2ap_messages_types.h>
+#include <openair2/COMMON/m2ap_messages_types.h>
+#include <openair2/COMMON/m3ap_messages_types.h>
 #include <openair2/COMMON/sctp_messages_types.h>
 #include <openair2/COMMON/udp_messages_types.h>
 #include <openair2/COMMON/gtpv1_u_messages_types.h>
@@ -231,6 +233,7 @@ typedef struct IttiMsgText_s {
 #include <openair3/NAS/UE/user_defs.h>
 #include <openair3/NAS/UE/nas_ue_task.h>
 #include <openair3/S1AP/s1ap_eNB.h>
+#include <openair3/MME_APP/mme_app.h>
 //#include <proto.h>
 
 #include <openair3/GTPV1-U/gtpv1u_eNB_task.h>
@@ -289,8 +292,15 @@ typedef struct {
   TASK_DEF(TASK_RAL_ENB,  TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_S1AP,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_X2AP,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_M2AP_ENB,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_M2AP_MCE,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_M3AP,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_M3AP_MME,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_M3AP_MCE,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_SCTP,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_ENB_APP,  TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_MCE_APP,  TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_MME_APP,  TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_FLEXRAN_AGENT,TASK_PRIORITY_MED, 200, NULL, NULL) \
   TASK_DEF(TASK_PHY_UE,   TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_MAC_UE,   TASK_PRIORITY_MED,  200, NULL, NULL)  \
diff --git a/nfapi/open-nFAPI/nfapi/inc/nfapi.h b/nfapi/open-nFAPI/nfapi/inc/nfapi.h
index 29a0e504385..0f09efa78ab 100644
--- a/nfapi/open-nFAPI/nfapi/inc/nfapi.h
+++ b/nfapi/open-nFAPI/nfapi/inc/nfapi.h
@@ -44,10 +44,14 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end);
 uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
 uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
 uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
+uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
+uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
 
 uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
 uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
 uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
+uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
+uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
 
 typedef uint8_t (*pack_array_elem_fn)(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end);
 uint8_t packarray(void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t **ppWritePackedMsg, uint8_t *end, pack_array_elem_fn fn);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index a1a0b6e7245..0b27fe6f4ff 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
@@ -704,6 +704,23 @@ typedef struct {
 #define NFAPI_PUCCH_CONFIG_N_AN_CS_TAG 0x003E
 #define NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG 0x003F
 
+typedef struct{
+       nfapi_uint8_tlv_t mbsfn_area_idx;
+       nfapi_uint16_tlv_t mbsfn_area_id_r9;
+} nfapi_embms_sib13_config_t;
+#define NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG 0x0039
+#define NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG 0x0040
+
+typedef struct {
+       nfapi_tl_t tl;
+       uint16_t  num_mbsfn_config;
+       uint16_t  radioframe_allocation_period[8];
+       uint16_t  radioframe_allocation_offset[8];
+       uint8_t  fourframes_flag[8];
+       int32_t  mbsfn_subframeconfig[8];
+} nfapi_embms_mbsfn_config_t;
+#define NFAPI_EMBMS_MBSFN_CONFIG_TAG 0x0041
+
 typedef struct {
        nfapi_uint8_tlv_t radioframe_allocation_period;
        nfapi_uint8_tlv_t radioframe_allocation_offset;
@@ -1111,6 +1128,9 @@ typedef struct {
 	nfapi_prach_config_t prach_config;
 	nfapi_pusch_config_t pusch_config;
 	nfapi_pucch_config_t pucch_config;
+        // addition nfpai tlvs for embms MBSFN config //TOBE REVIEWED
+        nfapi_embms_sib13_config_t embms_sib13_config;
+        nfapi_embms_mbsfn_config_t embms_mbsfn_config;
 	nfapi_fembms_config_t fembms_config;
 	nfapi_srs_config_t srs_config;
 	nfapi_uplink_reference_signal_config_t uplink_reference_signal_config;
@@ -1133,6 +1153,9 @@ typedef struct {
 	nfapi_prach_config_t prach_config;
 	nfapi_pusch_config_t pusch_config;
 	nfapi_pucch_config_t pucch_config;
+        // addition nfpai tlvs for embms MBSFN config //TOBE REVIEWED
+        nfapi_embms_sib13_config_t embms_sib13_config;
+        nfapi_embms_mbsfn_config_t embms_mbsfn_config;
         nfapi_fembms_config_t fembms_config;
 	nfapi_srs_config_t srs_config;
 	nfapi_uplink_reference_signal_config_t uplink_reference_signal_config;
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c
index 3f017bc9a4a..156a48ec05d 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c
@@ -405,7 +405,116 @@ uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **ou
 		return 0;
 	}
 }
+uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
+{
+       if(len == 0)
+               return 1;
+
+       if(len > max_len)
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+               return 0;
+       }
+
+       if((end - (*in)) >= sizeof(uint32_t) * len)
+       {
+               uint32_t idx;
+               for(idx = 0; idx < len; ++idx)
+               {
+                       if(!pull32(in, &out[idx], end))
+                               return 0;
+               }
+
+               return sizeof(uint32_t) * len;
+       }
+       else
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+               return 0;
+       }
+}
 
+uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
+{
+       if(len == 0)
+               return 1;
+
+       if(len > max_len)
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+               return 0;
+       }
+
+       if((end - (*in)) >= sizeof(uint32_t) * len)
+       {
+               uint32_t idx;
+               for(idx = 0; idx < len; ++idx)
+               {
+                       if(!pulls32(in, &out[idx], end))
+                       return 0;
+               }
+
+               return sizeof(uint32_t) * len;
+       }
+       else
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+               return 0;
+       }
+}
+uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
+{
+       if(len == 0)
+               return 1;
+
+       if(len > max_len)
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+               return 0;
+       }
+
+       if((end - (*out)) >= sizeof(uint32_t) * len)
+       {
+               uint32_t idx;
+               for(idx = 0; idx < len; ++idx)
+               {
+                       if(!push32(in[idx], out, end))
+                               return 0;
+               }
+               return sizeof(uint32_t) * len;
+       }
+       else
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+               return 0;
+       }
+}
+uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
+{
+       if(len == 0)
+               return 1;
+
+       if(len > max_len)
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+               return 0;
+       }
+
+       if((end - (*out)) >= sizeof(uint32_t) * len)
+       {
+               uint32_t idx;
+               for(idx = 0; idx < len; ++idx)
+               {
+                       pushs32(in[idx], out, end);
+               }
+               return sizeof(uint32_t) * len;
+       }
+       else
+       {
+               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+               return 0;
+       }
+}
 uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
 {
 	if(len == 0)
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
index 54e27123d99..a8ac0f0a654 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
@@ -404,7 +404,26 @@ static uint8_t unpack_nmm_frequency_bands_value(void* tlv, uint8_t **ppReadPacke
 	return ( pull16(ppReadPackedMsg, &value->number_of_rf_bands, end) &&
 			 pullarray16(ppReadPackedMsg, value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, end));
 }
-
+static uint8_t pack_embms_mbsfn_config_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+       nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
+       
+       return ( push16(value->num_mbsfn_config, ppWritePackedMsg, end) &&
+                pusharray16(value->radioframe_allocation_period, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) &&
+                pusharray16(value->radioframe_allocation_offset, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) &&
+                pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) &&
+                pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end));
+}
+//static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end)
+//{
+//     nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
+//
+//     return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) &&
+//              pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) &&
+//              pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) &&
+//              pull8(ppReadPackedMsg, &value->fourframes_flag, end) &&
+//                      pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end));
+//}
 static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
 {
 	nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg;
@@ -461,6 +480,11 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_
 			pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
 			pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
 
+                       pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+                       pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+
+                       pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) &&
+
                        pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
                        pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
                        pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-- 
GitLab