Changes:
* Add comprehensive delay management (DM) and EWMA state variables (e.g., jitter estimates, risk debts, pressure holds, and safe margins) to `nfapi_vnf_p7_connection_info_t` in `vnf_p7.h`.
* Introduce integer-based EWMA math helpers (`p7_ewma_step_i32`, `calculate_slot_distance`, etc.) in `vnf_p7.c` to handle precise timing calculations and prevent integer dead-zones.
* Implement the core `vnf_nr_delay_management()` controller, which dynamically computes the optimal `slot_ahead` using a fast-attack/slow-release pressure model, risk/debt memory, and critical cliff region mapping.
* Integrate the delay controller into `vnf_nr_handle_timing_info()`, feeding it the timing statistics parsed from the PNF to continuously adjust pacing.
* Clean up extensive trailing whitespaces and formatting inconsistencies throughout `vnf_p7.c`.
Purpose:
To establish a robust, adaptive dynamic slot timing controller for the VNF. By leveraging an EWMA-based algorithm, the VNF can continuously track network jitter, estimate mean delays, and intelligently balance timing "debt" against "safe margins." This enables the VNF to proactively and smoothly adjust its transmission pacing (`slot_ahead`) to prevent late packet drops under varying network conditions, eliminating the abrupt and erratic timing jumps seen in the legacy sync implementation.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
Changes:
* **common/utils/system.c**: Change `pthread_setname_np` failure behavior from `AssertFatal` to a non-fatal `LOG_E` to prevent unnecessary crashes on thread creation.
* **nfapi_vnf.c / vnf_p7.c**: Introduce a dedicated `vnf_timing_thread` to autonomously drive the VNF slot timing using high-resolution `clock_nanosleep`.
* **vnf_p7.c**: Implement `vnf_nr_extract_timing_info()` to parse incoming PNF timing information and calculate dynamic statistics (worst late, worst early, and max jitter) instead of abruptly overriding SFN/slot.
* **vnf_p7_interface.c / vnf_p7.h**: Add thread-safe state management (`mutex`, `pthread_cond_t`) to ensure the timing thread waits for `initial_timinginfo_received` before starting its autonomous loop.
* **nr_fapi_p5.c / nfapi_vnf.c**: Add parsing and packing for P7 timing offset TLVs (`DL_TTI`, `UL_TTI`, `UL_DCI`, `TX_DATA`) in the P5 Param Response.
* **nfapi_vnf.c**: Update default P7 configuration, setting the `timing_window` to 4500 and enabling `periodic_timing`.
Purpose:
Previously, the VNF SFN/Slot advancement was tightly coupled to PNF timing indications, making the system highly sensitive to network jitter and resulting in unstable SFN/slot jumps when large delays occurred. By introducing an independent, autonomous timing thread on the VNF side, the system can now maintain a stable local slot clock while applying periodic synchronizations and burst catch-up mechanisms. Additionally, extracting comprehensive delay and jitter statistics from the PNF enables the upcoming dynamic slot sleep timing controller to make precise, mathematically sound adjustments without causing sudden timing disruptions.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
Changes:
* Fix unused variable warning in `nfapi_pnf.c` by scoping the `nfapi_nr_slot_indication_scf_t` definition inside the `#ifdef ENABLE_WLS` block.
* Add synchronization state variables (`slot_adjustment`, `us_adjustment`, `sync_locked`, `slot_duration_us`) and a thread-safe mutex to the `nfapi_vnf_p7_connection_info` struct in `vnf_p7.h`.
* Introduce dynamic target margin constants (`MARGIN_TOLERANCE_US`, `MARGIN_TOLERANCE_LOCKED_US`) to establish an adaptive deadband zone.
* Implement `timehr_diff_us()` in `vnf_p7.c` to correctly calculate signed microsecond differences while handling 12-bit second wrap-arounds (4096 seconds).
* Completely rewrite `vnf_nr_handle_ul_node_sync()` to calculate timing offset using the standard symmetric delay formula: `((T2 - T1) - (T4 - T3)) / 2`.
* Add 10.24s wrap-around protection to the offset calculation.
* Implement drift monitoring logic that stops continuous adjustments once synchronized, but automatically unlocks for re-calibration if the offset exceeds `MARGIN_TOLERANCE_LOCKED_US`.
Purpose:
The legacy UL node sync algorithm was overly complex, relying on cycle counts, moving averages, and trend filtering that were prone to instability, especially during timestamp wrap-arounds. The refactored synchronization algorithm simplifies the offset calculation, makes it mathematically rigorous, and handles 10.24s nFAPI timestamp limits safely. By introducing locked and unlocked tolerance margins (deadband zones), the system avoids thrashing with continuous micro-adjustments, ensuring more stable P7 slot timing. The minor change in `nfapi_pnf.c` resolves a compilation warning when WLS is not enabled.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
Rewrite the PNF-side timing infrastructure to fix wrap-around bugs,
implement RFC 3550 jitter, and unify per-message timing checks:
TIMEHR wrap-around fix (get_slot_time):
- Add timehr_diff_us() computing a signed difference that correctly
handles the 12-bit second field wrap-around (~4096 s cycle)
- Rewrite get_slot_time() using timehr_diff_us; remove the previous
implementation that mis-handled wrap-around
RFC 3550 jitter calculation (pnf_p7.c / pnf_p7.h):
- Introduce nfapi_jitter_msg_type_t enum for DL_TTI, UL_TTI, UL_DCI,
TX_DATA message types
- Add pnf_timehr_to_us(), pnf_update_jitter(), pnf_get_jitter(),
pnf_reset_jitter() implementing the RFC 3550 inter-arrival jitter
formula
- Call pnf_update_jitter() on each received P7 message
- pnf_p7.h: add jitter state fields and function declarations
Unified P7 timing check (check_nr_p7_timing):
- Add calc_slot_diff() helper for wrap-aware slot number comparison
- Introduce check_nr_p7_timing() replacing four separate copies of
the per-message timing validation; it computes margin, updates
latest_delay / earliest_arrival, logs out-of-window events, and
triggers aperiodic timing info via a flag rather than a direct send
- Add timing_info_aperiodic_send flag, timing_info_trigger_sfn/slot,
timing_info_last_send_time_hr, timing_window and per-message
timing_offset fields to pnf_p7_t
Fix pnf_nr_pack_and_send_timing_info:
- Compute last_sfn/last_slot as the previous slot per SCF 225
- Calculate elapsed time using timing_info_last_send_time_hr
- Populate latest_delay / earliest_arrival from tracked stats
- Use renamed tx_data_jitter (not tx_data_request_jitter)
pnf_p7_interface.c: propagate timing_window and per-message offsets
from pnf_p7_t during P7 start
Signed-off-by: dong881 <minghunghsu.taiwan@gmail.com>
fix(nfapi/pnf): stop sending slot_indication from PNF; remove duplicate slot counter
Per SCF 225, the slot.indication message originates at the VNF and flows
down to the PNF. The PNF must not echo it back.
- nfapi_pnf.c (handle_nr_slot_ind): comment out oai_nfapi_nr_slot_indication()
call; the VNF drives slot timing autonomously via its own timing thread
- nfapi_pnf.c (nr_start_resp_cb): set nr_start_resp_received flag so that
the VNF can track when the PNF has started
- socket_pnf.c (pnf_nr_p7_message_pump): remove the duplicate sfn/slot
increment inside the message pump loop; slot counting is handled by the
PNF processing path and must not be done twice
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
Implement SCF225 timing offset TLV handling for DL_TTI, UL_TTI, UL_DCI and
TX_DATA in request/response pack-unpack and runtime config propagation.
This enables message-specific timing offset negotiation between VNF and PNF.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
Stop hardcoding timing_window, timing_info_mode, and timing_info_period in
VNF PHY allocation. Initialize defaults in vnf config and propagate configured
values during VNF setup so deployments can tune timing behavior without code edits.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
Rename tx_data_request_* timing fields to tx_data_* in NR timing-related
structures and handling paths. This removes naming ambiguity and aligns
with current SCF 225 terminology used by timing info exchange.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
SCF 225 allows timing_window up to 30000us, which exceeds uint8 capacity.
Promote timing_window-related fields and pack/unpack paths to uint16 so
configuration values are represented consistently across VNF/PNF interfaces.
Signed-off-by: Ming-Hong HSU, BMW Lab@NTUST <m11302209@gapps.ntust.edu.tw>
an incorrect assertion that was enforcing symmetric antenna
configurations only. I removed the assertion and updated the logging for
UE antenna dimensions and the channel model antenna dimensions used to
search in CIRDB.
Signed-off-by: Merkebu Girmay <merkebu.girmay@openairinterface.org>
Preparatory changes for LDPC CUDA integration
This changeset is preparatory work to merge LDPC CUDA offload in !4097.
Notably, it includes changes for cleaning up some defines, updates to
the LDPC interface, and CI specific changes to prepare for the other MR.
The goal is to merge changes in a first step such that, in a second
step, only the actual LDPC CUDA implementation and ancillary changes
(CUDA memory allocations, CI files, ...) need to be merged.
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
This memset() seems to be superfluous: following the code flow,
d_to_be_cleared is set on the same condition which guards the memset.
Following nrLDPC_coding_decoder() -> nrLDPC_prepare_TB_decoding() ->
nr_process_decode_segment() -> nr_rate_matching_ldpc_rx(), another
memset() is done using d_to_be_cleared.
Reported-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
CI: Clone from internal git repo
This MR refactors the CI pipeline as a preparatory step for the GitLab
--> GitHub migration. The core idea is to use a dedicated stage
RAN-Local-Repo-Push (introduced in !4017 (merged)) to clone source and
target branches, merges them and push a resulting branch into internal
git mirror. All downstream test jobs then check out exclusively from
that mirror. This makes the CI subpipelines independent of the remote
repository and improves stability in case of disruptions - test jobs
always check out from the internal mirror, not from GitLab/GitHub
directly.
Changes:
- doGitLabMerge.sh removed - merge is now done once in
RAN-Local-Repo-Push, slave jobs check out the pre-merged branch from
the internal mirror via SCM RAN-Local-Repo-Push extended:
- mergeWithTarget boolean parameter makes the merge optional (skipped on
direct push events) source/target remotes replace reliance on origin,
- targetRepo is now a configurable parameter to support fork-based MRs
- CreateTag() removed from Python - testBranch and testRepository
(default: internal mirror) are computed in the Jenkinsfile and passed
directly, two optional override parameters (customBranch,
customRepository) allow targeting a non-default branch or repo
- create_workspace.sh is reduced to git clone --depth=1 --branch
- all eNB_/ran-prefixed Jenkinsfile parameters and Python CLI arguments
renamed to neutral names (sourceBranch, sourceCommit, workspace,
repository,...), both old and new names accepted during the transition
period
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
A later commit (for LDPC CUDA) will reuse add_physim_test(), but is in a
completely different location than the existing physim test definitions.
Hence, move it to global scope for later reuse.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Provide the memory buffer size for storing LLRs across HARQ rounds. then
we don't need to check for this in the API users.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Rename this option from CUDA_ENABLE, as it might otherwise conflict with
another option for LDPC CUDA. For consistency, name the compile option
to CHANNEL_SIM_CUDA. This way, the LDPC CUDA option (ENABLE_LDPC_CUDA
and compile definition LDPC_CUDA) will not conflict, and the
corresponding code is clearly "labelled".
A further change is the use of target_sources to simplify the definition
of the channel_pipeline executable.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Information about sourceBranch and sourceCommit is already encoded in
the testBranch name, making it redundant in the HTML header.
Also remove the Job Trigger and Target Branch lines, as these parameters
provide limited value and are not particularly relevant for the report.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
"Create new Workspace for server 0/1" no longer makes sense now that
workspace creation is not tied to a specific server index.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
NR_MAC/PHY: align SRS time_start_position semantics between L2 and L1
Problem
nfapi_nr_srs_pdu_t::time_start_position was being interpreted
inconsistently between OAI MAC (the producer) and the various L1
consumers:
- MAC populated the field with SRS-ResourceMapping.startPosition from
the RRC config — the value 3GPP defines as an offset counted backwards
from the end of the slot (TS 38.331).
- L1 consumers (openair1/PHY/NR_TRANSPORT/srs_rx.c,
openair1/SCHED_NR/phy_procedures_nr_gNB.c) and the MAC's own VRB-map
consumer (gNB_scheduler_srs.c) all re-derived the absolute symbol
index with NR_SYMBOLS_PER_SLOT - 1 - time_start_position.
This works for OAI's in-tree soft L1 (every consumer applies the same
inversion), but external FAPI L1s (NVIDIA Aerial / cuBB) treat
time_start_position as the absolute symbol index per the SCF FAPI 222
PDU semantics. The MAC and external L1 therefore disagreed by one symbol
inversion. Net effect: SRS was scheduled on the wrong OFDM symbol, the
RU sampled noise instead of the SRS, and the channel-matrix returned in
SRS.indication was all zeros for almost every occasion. Fix
Move the inversion to the producer side. MAC populates the PDU with the
absolute symbol index (NR_SYMBOLS_PER_SLOT - 1 - startPosition), and
every consumer uses srs_pdu->time_start_position directly as l0.
The two semantics are mathematically equivalent for OAI's soft L1 (l0 =
NR_SYMBOLS_PER_SLOT - 1 - startPosition either way), so the symbol index
used internally is unchanged on non-Aerial builds. External L1 consumers
now receive the value they expect. Testing status
- [x] OAI L1 + L2
- [x] Aerial L1 in CAT-B / mMIMO mode
- [x] Aerial L1 in CAT-A mode
- [x] RFsim / nrUE end-to-end loopback:
Reviewed-By: Rúben Soares Silva <rsilva@allbesmart.pt>
Add Fedora 44/Ubuntu 26 to list of supported distributions
See commits for more details. Includes a minor cleanup. What I tested
for U22/U24/U26 and F44 is
./build_oai --ninja -c -I -w USRP --gNB --nrUE
Reviewed-By: Luis Pereira <lpereira@allbesmart.pt>
changes in cudaMemadvise/cudaPrefetch API for v13.
Build fails on DGX spark or any Blackwell GPU target without this fix.
It just checks the CUDA version in a couple of places where GPU offload
is used for channel simulation (nr_dlsim,nr_ulsim and
channel_pipeline.cu) and adapts the usage of the CUDA API accordingly.
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Remove CreateTag() and the merge/targetBranch parameters from
CreateWorkspace, passing the final branch name and repository directly
from Jenkins instead. Jenkinsfile computes testBranch and testRepository
(with INTERNAL_REPO as default). create_workspace.sh now does a simple
shallow clone by branch name.
Introduce two optional Jenkins parameters that allow overriding the
default branch reference and git repository URL used across the CI
pipeline.
- customBranch: when set, replaces the entire computed
{sourceBranch}-{commitID}
- customRepository: when set, replaces INTERNAL_REPO as the git remote
used by Create_Workspace to clone the source code onto the test node.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Use the current OAI CI default UHD version. Update the documentation to
show how to install a recent version.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The existing patch (generated through sed) works also in UHD versions
beyond 4.8, so allow to use that.
Further, since sed is confusing, store the patch directly. Update the
dockerfiles so that docker copies the right file for UHD 4.8.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Also, for UHD install from packages, add the right version for both
Ubuntu 24 and Ubuntu 26: in U24, use the currently recommended 4.8, and
bump to latest in U26.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The CI does not use installation of UHD from package, hence this
mechanism is not needed (and should not be, anyway).
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Iterate all NZP-CSI-RS resources per ResourceSet in scheduler
It was necessary to use 2 CSI-RS resources, but it was discovered that
gNB only transmitted the first one.
nr_csirs_scheduling() was comparing nzp_CSI_RS_ResourceId against an
NZP-CSI-RS-ResourceSetId picked from the first entry of the first
matching CSI-ResourceConfig. This silently filtered out every Resource
whose ID did not happen to match the ResourceSet ID, making setups with
more than one NZP-CSI-RS-Resource per UE impossible: only the first
resource was ever transmitted, while the UE kept scheduling reception
for the remaining ones and reported them as missing (RSRP at the noise
floor).
This MR fixes it, and allows multiple Resources per Set.
Reviewed-By: Francesco Mani <email@francescomani.it>
hotfix for correct GFNI detection
Currently, GFNI will be activated for all x86 builds which fails on
older machines (prior to skylake or Zen4). This patch just detects GFNI
from the CPUFLAGS and adds only if it is supported by the x86 target.
Includes two ancillary fixes for correctly using CPUFLAGS and DFTS
compiler optimization flag.
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
NAS UE Service Request fixes and improvements for Paging
This MR improves the NAS UE Service Request path and makes
paging-related resume handling more robust. It fixes KSI/KgNB
synchronization, corrects 5G-S-TMSI and encoder/decoder length handling,
and adds Service Accept handling in the NAS_CONN_ESTABLI_CNF path.
It also zero-initializes the initial NAS buffer used during RRC setup
complete to avoid carrying stale data into early NAS message handling.
Reviewed-By: Cedric Roux <cedric.roux@eurecom.fr>
Refactor DLSCH/ULSCH scheduler: extract proportional fair policy behind function pointer interface
Motivation
The current `pf_dl()` is a ~600-line monolithic function that mixes
infrastructure concerns (UE iteration, HARQ management, CCE allocation,
MAC PDU generation) with the scheduling policy (PF priority, RB
allocation, MCS selection). This makes it hard to modify the scheduling
strategy, test alternatives, or offload scheduling to a GPU (cuMAC).
This MR refactors the DL and UL schedulers into a clean separation
between **infrastructure** and **policy**, using function pointers for
beam allocation and scheduling decisions. The data structures
(`nr_dl_candidate_t`, `nr_dl_sched_params_t`) are also designed to map
directly to cuMAC's
`cumacCellGrpUeStatus`/`cumacSchdSol`/`CumacCellGrpPrms`, to make future
integration smooth.
Changes
Goodput tracking fix
`dl_thr_ue` now tracks actual goodput in bps (EWMA of SDU byte deltas
per frame) instead of accumulating raw byte counts per slot, which are
not as straightforward to interpret (due to variations in TDD patterns
mostly). The new calculation matches closely with the throughput
measured with e.g. iperf.
Helper extraction from `pf_dl()` and `post_process_dlsch()`
- `find_first_available_rbs()` — first-fit contiguous RB allocation
- `setup_dl_harq_process()` — HARQ process management
- `generate_dl_mac_pdu()` — MAC CE + RLC data + padding
- `fill_dl_tx_request()` — FAPI TX_req filling
New scheduling interface
- **`nr_dl_candidate_t`** — per-UE flat struct with all immutable inputs
(buffer status, BLER, MCS limits, beam, BWP) and outputs (scheduled,
rbStart, rbSize, MCS). Kept relatively minimal for now, but it should
be easy to add more input metrics in the future.
- **`nr_dl_sched_params_t`** — per-beam cell-level context (VRB map,
available RBs, slot bitmap)
Function pointers (DL)
| Pointer | Default implementation | Role |
|---------|----------------------|------|
| `dl_ri_pmi_select` | `nr_dl_ri_pmi_select_default` | Rank/PMI selection |
| `dl_beam_select` | `nr_dl_beam_select_default` | Beam direction assignment |
| `dl_tda_select` | `nr_dl_tda_select_default` | Time-domain allocation |
| `dl_mcs_select` | `nr_dl_mcs_select_default` | MCS from BLER/SINR |
| `dl_rb_alloc` | `nr_dl_proportional_fair` | PRB allocation (PF policy) |
Function pointers (UL)
| Pointer | Default implementation | Role |
|---------|----------------------|------|
| `ul_ri_tpmi_select` | `nr_ul_ri_tpmi_select_default` | Rank/TPMI from SRS feedback |
| `ul_beam_select` | `nr_ul_beam_select_default` | Beam direction assignment |
| `ul_tda_select` | `nr_ul_tda_select_default` | Time-domain allocation |
| `ul_mcs_select` | `nr_ul_mcs_select_default` | MCS from BLER/SINR |
| `ul_rb_alloc` | `nr_ul_proportional_fair` | PRB allocation (retx first, then PF-sorted new-tx) |
All default implementations are in `gNB_scheduler_dlsch.c` (DL) and
`gNB_scheduler_ulsch.c` (UL).
MCS selection flow
The old `get_mcs_from_bler()` entangled two concerns: updating the BLER
estimate from HARQ feedback and deciding the MCS. These are now split:
- **BLER tracking is infrastructure's job**: `collect_dl_candidates()`
calls `update_dl_bler_stats()` which updates the BLER estimate from
HARQ round statistics.
- **MCS selection is the policy's job**: the proportional fair policy
calls `select_mcs_from_bler()` internally to adapt MCS based on the
BLER value. A different policy could use an entirely different MCS
strategy (e.g. cuMAC has its own `mcsSelectionLUT` + OLLA, one could
decide to opportunistically lower the MCS while increasing the PRB
allocation for reliability in some cases, etc).
For retransmissions, MCS/number of PRBs are passed as hints so the
policy can use them as-is if desired, but we don't enforce it (adaptive
HARQ possible too: the standard requires us to maintain TBS but in
theory it could be achieved via changing the MCS and number of RBs if we
wanted to).
Refactored flow
`nr_dl_schedule()` (formerly `pf_dl()`):
```
collect_dl_candidates() → build candidate array from UE list
schedule_dl_ues() → beam alloc + per-beam policy calls
for each scheduled candidate → CCE/PUCCH/TBS validation + post_process
```
Beam allocation and scheduling policy are two separate function
pointers, allowing each to be developed and tested independently (with
the goal in the future to add a parameter in the config file for each,
and telnet commands to hotswap).
`schedule_dl_ues()` wraps both into a single function: it first calls
beam allocation to assign candidates to beams, then iterates over beams
and calls the scheduling policy for each one. cuMAC performs joint beam
+ PRB allocation on the GPU, so when integrating later it will replace
`schedule_dl_ues()`.
Future work
- Channel matrix H from SRS on candidates for beam-aware scheduling
- Per-RB channel magnitude derived from SRS on candidates
- Config file parameters and telnet commands for hotswapping policies
- cuMAC integration via `schedule_dl_ues()` replacement
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
This helps the performance: In the FFTs there is a chain like
dft1024->dft256->dft64->dft16 with nested function calls. This improves
the compilers behaviour when handling the nesting.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Currently, GFNI will be activated for all x86 builds which fails on
older machines (prior to skylake or Zen4). Properly detect based on CPU
flags.
Signed-off-by: Raymond Knopp <raymond.knopp@eurecom.fr>
Process Service Accept when it is delivered through NAS connection
establish confirm.
Changes:
- add `FGS_SERVICE_ACCEPT` branch in `NAS_CONN_ESTABLI_CNF` message
dispatch and call `handle_service_accept
Refs:
- TS 24.501 5.6.1.4, 8.2.17 (Service accept)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>