lte/gateway/c/core/oai/tasks/amf/nas5g_message.cpp
/****************************************************************************
 *                                                                           *
 *   Name:  nas5g_message_decode()                                           *
 *                                                                           *
 *   Description: Decode layer 3 NAS message                                 *
 *                                                                           *
 *   Inputs:  buffer:  Pointer to the buffer containing layer 3              *
 *                     NAS message data                                      *
 *            length:  Number of bytes that should be decoded                *
 *            security:  security context                                    *
 *            Others:  None                                                  *
 *                                                                           *
 *   Outputs: msg:   L3 NAS message structure to be filled                   *
 *            Return:  The number of bytes in the buffer if the              *
 *                     data have been successfully decoded;                  *
 *                     A negative error code otherwise.                      *
 *            Others:  Return the computed mac if security context is        *
 *                     established                                           *
 *                                                                           *
 ****************************************************************************/


Decode layer 3 NAS message

Pointer to the buffer containing layer 3
NAS message data
length:  Number of bytes that should be decoded
security:  security context
Others:  None

L3 NAS message structure to be filled
Return:  The number of bytes in the buffer if the
data have been successfully decoded;
A negative error code otherwise.
Others:  Return the computed mac if security context is
established
Decode layer 3 NAS message Pointer to the buffer containing layer 3 NAS message data length : Number of bytes that should be decoded security : security context Others : None L3 NAS message structure to be filled Return : The number of bytes in the buffer if the data have been successfully decoded ; A negative error code otherwise . Others : Return the computed mac if security context is established
int nas5g_message_decode(
    const unsigned char* const buffer, amf_nas_message_t* msg, uint32_t length,
    void* security, amf_nas_message_decode_status_t* status) {
  OAILOG_FUNC_IN(LOG_AMF_APP);
  amf_security_context_t* amf_security_context =
      (amf_security_context_t*) security;
  int bytes    = 0;
  uint32_t mac = 0;
  int size     = 0;
  bool is_sr   = false;
  if (amf_security_context) {
    status->security_context_available = 1;
  }
  size =
      nas5g_message_header_decode(buffer, &msg->header, length, status, &is_sr);
  if (size < 0) {
    OAILOG_ERROR(LOG_AMF_APP, "NAS Header decode failed");
    OAILOG_FUNC_RETURN(LOG_AMF_APP, TLV_BUFFER_TOO_SHORT);
  }
  if (size > 2) {
    int offset = size - sizeof(uint8_t);
    if (amf_security_context) {
      status->security_context_available = 1;
      if (SECU_DIRECTION_UPLINK == amf_security_context->direction_decode) {
        if (amf_security_context->ul_count.seq_num >
            msg->header.sequence_number) {
          amf_security_context->ul_count.overflow += 1;
        }
        amf_security_context->ul_count.seq_num = msg->header.sequence_number;
      } else {
        if (amf_security_context->dl_count.seq_num >
            msg->header.sequence_number) {
          amf_security_context->dl_count.overflow += 1;
        }
        amf_security_context->dl_count.seq_num = msg->header.sequence_number;
      }
      mac = _nas5g_message_get_mac(
          buffer + offset, length - offset,
          amf_security_context->direction_decode, amf_security_context);
      if (mac == msg->header.message_authentication_code) {
        status->mac_matched = 1;
      } else {
        OAILOG_DEBUG(
            LOG_AMF_APP,
            "msg->header.message_authentication_code = %04X != computed = "
            "%04X\n",
            msg->header.message_authentication_code, mac);
      }
    }
    bytes = _nas5g_message_protected_decode(
        (unsigned char* const)(buffer + size), &msg->header, &msg->plain,
        length - size, amf_security_context, status);
  } else {
    bytes =
        _nas5g_message_plain_decode(buffer, &msg->header, &msg->plain, length);
  }
  if (bytes < 0) {
    OAILOG_ERROR(LOG_AMF_APP, "NAS Decode failed");
    OAILOG_FUNC_RETURN(LOG_AMF_APP, bytes);
  }
  OAILOG_DEBUG(
      LOG_AMF_APP, "[%s] Msg plain decode bytes[0-%d]\n%s",
      get_message_type_str(msg->plain.amf.header.message_type).c_str(), bytes,
      uint8_to_hex_string(buffer, bytes).c_str());
  OAILOG_INFO(
      LOG_AMF_APP, "Decoded msg(nas5g) id: [%x]-name [%s]",
      msg->plain.amf.header.message_type,
      get_message_type_str(msg->plain.amf.header.message_type).c_str());
  if (size > 1) {
    OAILOG_FUNC_RETURN(LOG_AMF_APP, size + bytes);
  }
  OAILOG_FUNC_RETURN(LOG_AMF_APP, bytes);
}
int nas5g_message_decode ( const unsigned char * const buffer , amf_nas_message_t * msg , uint32_t length , void * security , amf_nas_message_decode_status_t * status ) { OAILOG_FUNC_IN ( LOG_AMF_APP ) ; amf_security_context_t * amf_security_context = ( amf_security_context_t * ) security ; int bytes = 0 ; uint32_t mac = 0 ; int size = 0 ; bool is_sr = false ; if ( amf_security_context ) { status -> security_context_available = 1 ; } size = nas5g_message_header_decode ( buffer , & msg -> header , length , status , & is_sr ) ; if ( size < 0 ) { OAILOG_ERROR ( LOG_AMF_APP , " " ) ; OAILOG_FUNC_RETURN ( LOG_AMF_APP , TLV_BUFFER_TOO_SHORT ) ; } if ( size > 2 ) { int offset = size - sizeof ( uint8_t ) ; if ( amf_security_context ) { status -> security_context_available = 1 ; if ( SECU_DIRECTION_UPLINK == amf_security_context -> direction_decode ) { if ( amf_security_context -> ul_count . seq_num > msg -> header . sequence_number ) { amf_security_context -> ul_count . overflow += 1 ; } amf_security_context -> ul_count . seq_num = msg -> header . sequence_number ; } else { if ( amf_security_context -> dl_count . seq_num > msg -> header . sequence_number ) { amf_security_context -> dl_count . overflow += 1 ; } amf_security_context -> dl_count . seq_num = msg -> header . sequence_number ; } mac = _nas5g_message_get_mac ( buffer + offset , length - offset , amf_security_context -> direction_decode , amf_security_context ) ; if ( mac == msg -> header . message_authentication_code ) { status -> mac_matched = 1 ; } else { OAILOG_DEBUG ( LOG_AMF_APP , " " " \n " , msg -> header . message_authentication_code , mac ) ; } } bytes = _nas5g_message_protected_decode ( ( unsigned char * const ) ( buffer + size ) , & msg -> header , & msg -> plain , length - size , amf_security_context , status ) ; } else { bytes = _nas5g_message_plain_decode ( buffer , & msg -> header , & msg -> plain , length ) ; } if ( bytes < 0 ) { OAILOG_ERROR ( LOG_AMF_APP , " " ) ; OAILOG_FUNC_RETURN ( LOG_AMF_APP , bytes ) ; } OAILOG_DEBUG ( LOG_AMF_APP , " \n " , get_message_type_str ( msg -> plain . amf . header . message_type ) . c_str ( ) , bytes , uint8_to_hex_string ( buffer , bytes ) . c_str ( ) ) ; OAILOG_INFO ( LOG_AMF_APP , " " , msg -> plain . amf . header . message_type , get_message_type_str ( msg -> plain . amf . header . message_type ) . c_str ( ) ) ; if ( size > 1 ) { OAILOG_FUNC_RETURN ( LOG_AMF_APP , size + bytes ) ; } OAILOG_FUNC_RETURN ( LOG_AMF_APP , bytes ) ; }
Name:  nas5g_message_decode()
Name : nas5g_message_decode ()
/*
   * Decode the header
   */ // found security header /*
     * Compute offset of the sequence number field
     */ /*
       * Compute the NAS message authentication code, return 0 if no security
       * context
       */ /*
       * Check NAS message integrity
       */ /*
     * Decode security protected NAS message
     */ /*
     * Decode plain NAS message
     */ // Security Protected NAS message decoded