Files
openairinterface5g/openair3/NAS/COMMON/API/NETWORK/as_message.c
T
2025-01-08 20:11:09 +01:00

368 lines
12 KiB
C

/*
* 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
*/
/*****************************************************************************
Source as_message.c
Version 0.1
Date 2012/11/06
Product NAS stack
Subsystem Application Programming Interface
Author Frederic Maurel
Description Defines the messages supported by the Access Stratum sublayer
protocol (usually RRC and S1AP for E-UTRAN) and functions used
to encode and decode
*****************************************************************************/
#include "as_message.h"
#include "commonDef.h"
#include "nas_log.h"
#include <string.h> // memcpy
#include <stdlib.h> // free
/****************************************************************************/
/**************** E X T E R N A L D E F I N I T I O N S ****************/
/****************************************************************************/
/****************************************************************************/
/******************* L O C A L D E F I N I T I O N S *******************/
/****************************************************************************/
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
/****************************************************************************
** **
** Name: as_message_decode() **
** **
** Description: Decode AS message and accordingly fills data structure **
** **
** Inputs: buffer: Pointer to the buffer containing the **
** message **
** length: Number of bytes that should be decoded **
** Others: None **
** **
** Outputs: msg: AS message structure to be filled **
** Return: The AS message identifier when the buffer **
** has been successfully decoded; **
** RETURNerror otherwise. **
** Others: None **
** **
***************************************************************************/
int as_message_decode(const char* buffer, as_message_t* msg, int length)
{
LOG_FUNC_IN;
/* pointers to msg fields possibly not aligned because msg points to a packed structure
* Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and
* gcc, from v9, now warns about it. fix these warnings by removing the indirection on data
* (in fact i don't understand this code data seems to be useless...)
*/
/* Get the message type */
msg->msgID = *(uint16_t*)(buffer);
int bytes = 0;
switch (msg->msgID) {
case AS_NAS_ESTABLISH_REQ:
/* NAS signalling connection establish request */
bytes = sizeof(uint16_t) + sizeof(nas_establish_req_t) - sizeof(as_nas_info_t);
break;
case AS_NAS_ESTABLISH_IND:
/* NAS signalling connection establishment indication */
bytes = sizeof(uint16_t) + sizeof(nas_establish_ind_t) - sizeof(as_nas_info_t);
break;
case AS_NAS_ESTABLISH_RSP:
/* NAS signalling connection establishment response */
bytes = sizeof(uint16_t) + sizeof(nas_establish_rsp_t) - sizeof(as_nas_info_t);
break;
case AS_NAS_ESTABLISH_CNF:
/* NAS signalling connection establishment confirm */
bytes = sizeof(uint16_t) + sizeof(nas_establish_cnf_t) - sizeof(as_nas_info_t);
break;
case AS_UL_INFO_TRANSFER_REQ:
/* Uplink L3 data transfer request */
bytes = sizeof(uint16_t) + sizeof(ul_info_transfer_req_t) - sizeof(as_nas_info_t);
break;
case AS_UL_INFO_TRANSFER_IND:
/* Uplink L3 data transfer indication */
bytes = sizeof(uint16_t) + sizeof(ul_info_transfer_ind_t) - sizeof(as_nas_info_t);
break;
case AS_DL_INFO_TRANSFER_REQ:
/* Downlink L3 data transfer request */
bytes = sizeof(uint16_t) + sizeof(dl_info_transfer_req_t) - sizeof(as_nas_info_t);
break;
case AS_DL_INFO_TRANSFER_IND:
/* Downlink L3 data transfer indication */
bytes = sizeof(uint16_t) + sizeof(dl_info_transfer_ind_t) - sizeof(as_nas_info_t);
break;
case AS_BROADCAST_INFO_IND:
case AS_CELL_INFO_REQ:
case AS_CELL_INFO_CNF:
case AS_CELL_INFO_IND:
case AS_PAGING_REQ:
case AS_PAGING_IND:
case AS_NAS_RELEASE_REQ:
case AS_UL_INFO_TRANSFER_CNF:
case AS_DL_INFO_TRANSFER_CNF:
case AS_NAS_RELEASE_IND:
case AS_RAB_ESTABLISH_REQ:
case AS_RAB_ESTABLISH_IND:
case AS_RAB_ESTABLISH_RSP:
case AS_RAB_ESTABLISH_CNF:
case AS_RAB_RELEASE_REQ:
case AS_RAB_RELEASE_IND:
/* Messages without dedicated NAS information */
bytes = length;
break;
default:
bytes = 0;
LOG_TRACE(WARNING, "NET-API - AS message 0x%x is not valid",
msg->msgID);
break;
}
if (bytes > 0) {
/* Decode the message */
memcpy(msg, buffer, bytes);
LOG_FUNC_RETURN (msg->msgID);
}
LOG_TRACE(WARNING, "NET-API - Failed to decode AS message 0x%x",
msg->msgID);
LOG_FUNC_RETURN (RETURNerror);
}
/****************************************************************************
** **
** Name: as_message_encode() **
** **
** Description: Encode AS message **
** **
** Inputs: msg: AS message structure to encode **
** length: Maximal capacity of the output buffer **
** Others: None **
** **
** Outputs: buffer: Pointer to the encoded data buffer **
** Return: The number of characters in the buffer **
** when data have been successfully encoded; **
** RETURNerror otherwise. **
** Others: None **
** **
***************************************************************************/
int as_message_encode(char* buffer, as_message_t* msg, int length)
{
LOG_FUNC_IN;
int bytes = sizeof(msg->msgID);
as_nas_info_t nas_msg;
uint8_t* dataptr = NULL;
uint32_t len=0;
memset(&nas_msg, 0, sizeof(as_nas_info_t));
switch (msg->msgID) {
case AS_BROADCAST_INFO_IND:
/* Broadcast information */
bytes += sizeof(broadcast_info_ind_t);
break;
case AS_CELL_INFO_REQ:
/* Cell information request */
bytes += sizeof(cell_info_req_t);
break;
case AS_CELL_INFO_CNF:
/* Cell information response */
bytes += sizeof(cell_info_cnf_t);
break;
case AS_CELL_INFO_IND:
/* Cell information indication */
bytes += sizeof(cell_info_ind_t);
break;
case AS_PAGING_REQ:
/* Paging information request */
bytes += sizeof(paging_req_t);
break;
case AS_PAGING_IND:
/* Paging information indication */
bytes += sizeof(paging_ind_t);
break;
case AS_NAS_ESTABLISH_REQ:
/* NAS signalling connection establish request */
bytes += sizeof(nas_establish_req_t) - sizeof(uint8_t*);
nas_msg = msg->msg.nas_establish_req.initialNasMsg;
break;
case AS_NAS_ESTABLISH_IND:
/* NAS signalling connection establish indication */
bytes += sizeof(nas_establish_ind_t) - sizeof(uint8_t*);
nas_msg = msg->msg.nas_establish_ind.initialNasMsg;
dataptr = (uint8_t*)&(msg->msg.nas_establish_ind.initialNasMsg.nas_data);
len=msg->msg.nas_establish_ind.initialNasMsg.length;
break;
case AS_NAS_ESTABLISH_RSP:
/* NAS signalling connection establish response */
bytes += sizeof(nas_establish_rsp_t) - sizeof(uint8_t*);
nas_msg = msg->msg.nas_establish_rsp.nasMsg;
break;
case AS_NAS_ESTABLISH_CNF:
/* NAS signalling connection establish confirm */
bytes += sizeof(nas_establish_cnf_t) - sizeof(uint8_t*);
nas_msg = msg->msg.nas_establish_cnf.nasMsg;
dataptr = (uint8_t*)&(msg->msg.nas_establish_cnf.nasMsg.nas_data);
len=msg->msg.nas_establish_ind.initialNasMsg.length;
break;
case AS_NAS_RELEASE_REQ:
/* NAS signalling connection release request */
bytes += sizeof(nas_release_req_t);
break;
case AS_NAS_RELEASE_IND:
/* NAS signalling connection release indication */
bytes += sizeof(nas_release_ind_t);
break;
case AS_UL_INFO_TRANSFER_REQ:
/* Uplink L3 data transfer request */
bytes += sizeof(ul_info_transfer_req_t) - sizeof(uint8_t*);
nas_msg = msg->msg.ul_info_transfer_req.nasMsg;
break;
case AS_UL_INFO_TRANSFER_CNF:
/* Uplink L3 data transfer confirm */
bytes += sizeof(ul_info_transfer_cnf_t);
break;
case AS_UL_INFO_TRANSFER_IND:
/* Uplink L3 data transfer indication */
bytes += sizeof(ul_info_transfer_ind_t) - sizeof(uint8_t*);
nas_msg = msg->msg.ul_info_transfer_ind.nasMsg;
break;
case AS_DL_INFO_TRANSFER_REQ:
/* Downlink L3 data transfer */
bytes += sizeof(dl_info_transfer_req_t) - sizeof(uint8_t*);
nas_msg = msg->msg.dl_info_transfer_req.nasMsg;
break;
case AS_DL_INFO_TRANSFER_CNF:
/* Downlink L3 data transfer confirm */
bytes += sizeof(dl_info_transfer_cnf_t);
break;
case AS_DL_INFO_TRANSFER_IND:
/* Downlink L3 data transfer indication */
bytes += sizeof(dl_info_transfer_ind_t) - sizeof(uint8_t*);
nas_msg = msg->msg.dl_info_transfer_ind.nasMsg;
break;
case AS_RAB_ESTABLISH_REQ:
/* Radio Access Bearer establishment request */
bytes += sizeof(rab_establish_req_t);
break;
case AS_RAB_ESTABLISH_IND:
/* Radio Access Bearer establishment indication */
bytes += sizeof(rab_establish_ind_t);
break;
case AS_RAB_ESTABLISH_RSP:
/* Radio Access Bearer establishment response */
bytes += sizeof(rab_establish_rsp_t);
break;
case AS_RAB_ESTABLISH_CNF:
/* Radio Access Bearer establishment confirm */
bytes += sizeof(rab_establish_cnf_t);
break;
case AS_RAB_RELEASE_REQ:
/* Radio Access Bearer release request */
bytes += sizeof(rab_release_req_t);
break;
case AS_RAB_RELEASE_IND:
/* Radio Access Bearer release indication */
bytes += sizeof(rab_release_ind_t);
break;
default:
LOG_TRACE(WARNING, "NET-API - AS message 0x%x is not valid",
msg->msgID);
bytes = length;
break;
}
if (length > bytes) {
/* Encode the AS message */
memcpy(buffer, (unsigned char*)msg, bytes);
if ( (dataptr!=NULL) && (len > 0) ) {
/* Copy the NAS message */
memcpy(buffer + bytes, nas_msg.nas_data, nas_msg.length);
bytes += len;
/* Release NAS message memory */
free(nas_msg.nas_data);
len=0;
dataptr = NULL;
}
LOG_FUNC_RETURN (bytes);
}
LOG_TRACE(WARNING, "NET-API - Failed to encode AS message 0x%x",
msg->msgID);
LOG_FUNC_RETURN (RETURNerror);
}
/****************************************************************************/
/********************* L O C A L F U N C T I O N S *********************/
/****************************************************************************/