/*****************************************************************************
			Eurecom OpenAirInterface 3
			Copyright(c) 2012 Eurecom

Source		nas_process.c

Version		0.1

Date		2013/04/16

Product		Access-Stratum sublayer simulator

Subsystem	NAS message processing

Author		Frederic Maurel

Description	Defines functions executed by the Access-Stratum sublayer
		upon receiving NAS messages.

*****************************************************************************/

#include "nas_process.h"

#include "nas_data.h"
#include "nas_message.h"

#include <stdio.h>	// snprintf
#include <string.h>	// memset

/****************************************************************************/
/****************  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  *******************/
/****************************************************************************/

/*
 *-----------------------------------------------------------------------------
 *	   Functions used to process EPS Mobility Management messages
 *----------------------------------------------------------------------------- 
 */
static int _nas_process_emm(char* buffer, int length, const EMM_msg* msg);

static int _attach_request(char* buffer, int length, const attach_request_msg* msg);
static int _attach_accept(char* buffer, int length, const attach_accept_msg* msg);
static int _attach_reject(char* buffer, int length, const attach_reject_msg* msg);
static int _attach_complete(char* buffer, int length, const attach_complete_msg* msg);

static int _detach_request(char* buffer, int length, const detach_request_msg* msg);
static int _detach_accept(char* buffer, int length, const detach_accept_msg* msg);

static int _identity_request(char* buffer, int length, const identity_request_msg* msg);
static int _identity_response(char* buffer, int length, const identity_response_msg* msg);

static int _authentication_request(char* buffer, int length, const authentication_request_msg* msg);
static int _authentication_response(char* buffer, int length, const authentication_response_msg* msg);
static int _authentication_failure(char* buffer, int length, const authentication_failure_msg* msg);
static int _authentication_reject(char* buffer, int length, const authentication_reject_msg* msg);

static int _security_mode_command(char* buffer, int length, const security_mode_command_msg* msg);
static int _security_mode_complete(char* buffer, int length, const security_mode_complete_msg* msg);
static int _security_mode_reject(char* buffer, int length, const security_mode_reject_msg* msg);

static int _esm_message_container(char* buffer, int length, const EsmMessageContainer* msg);

static int _emm_status(char* buffer, int length, const emm_status_msg* msg);

/*
 *-----------------------------------------------------------------------------
 *	   Functions used to process EPS Session Management messages
 *----------------------------------------------------------------------------- 
 */
static int _nas_process_esm(char* buffer, int length, const ESM_msg* msg);

static int _pdn_connectivity_request(char* buffer, int length, const pdn_connectivity_request_msg* msg);
static int _pdn_connectivity_reject(char* buffer, int length, const pdn_connectivity_reject_msg* msg);

static int _pdn_disconnect_request(char* buffer, int length, const pdn_disconnect_request_msg* msg);
static int _pdn_disconnect_reject(char* buffer, int length, const pdn_disconnect_reject_msg* msg);

static int _activate_default_eps_bearer_context_request(char* buffer, int length, const activate_default_eps_bearer_context_request_msg* msg);
static int _activate_default_eps_bearer_context_accept(char* buffer, int length, const activate_default_eps_bearer_context_accept_msg* msg);
static int _activate_default_eps_bearer_context_reject(char* buffer, int length, const activate_default_eps_bearer_context_reject_msg* msg);

static int _activate_dedicated_eps_bearer_context_request(char* buffer, int length, const activate_dedicated_eps_bearer_context_request_msg* msg);
static int _activate_dedicated_eps_bearer_context_accept(char* buffer, int length, const activate_dedicated_eps_bearer_context_accept_msg* msg);
static int _activate_dedicated_eps_bearer_context_reject(char* buffer, int length, const activate_dedicated_eps_bearer_context_reject_msg* msg);

static int _deactivate_eps_bearer_context_request(char* buffer, int length, const deactivate_eps_bearer_context_request_msg* msg);
static int _deactivate_eps_bearer_context_accept(char* buffer, int length, const deactivate_eps_bearer_context_accept_msg* msg);

static int _esm_status(char* buffer, int length, const esm_status_msg* msg);

/****************************************************************************/
/******************  E X P O R T E D    F U N C T I O N S  ******************/
/****************************************************************************/

/*
 *----------------------------------------------------------------------------- 
 *                              Process NAS message
 *----------------------------------------------------------------------------- 
 */
int
nas_process(
    char* buffer,
    int length,
    const char* msg,
    int size)
{
    int index = 0;
    int bytes;
    nas_message_t nas_msg;

    /* Decode NAS message */
    memset(&nas_msg, 0, sizeof(nas_message_t));
    bytes = nas_message_decode(msg, &nas_msg, size);
    if (bytes < 0) {
        printf("ERROR\t: %s - Failed to decode NAS message (err=%d)\n",
            __FUNCTION__, bytes);
        return (RETURNerror);
    }

    int protocol_discriminator = nas_msg.header.protocol_discriminator;
    if (protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
        /* Process EPS Mobility Management NAS message */
        index += _nas_process_emm(buffer + index,
            length - index,
            &nas_msg.plain.emm);
    }
    else if (protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
        /* Process EPS Session Management NAS message */
        index += _nas_process_esm(buffer + index,
            length - index,
            &nas_msg.plain.esm);
    }
    else {
        printf("ERROR\t: %s - Protocol discriminator is not valid (%d)\n",
            __FUNCTION__, protocol_discriminator);
        return (RETURNerror);
    }

    buffer[index] = '\0';

    return (bytes);
}

/****************************************************************************/
/*********************  L O C A L    F U N C T I O N S  *********************/
/****************************************************************************/

/*
 * =============================================================================
 *	    Functions used to process EPS Mobility Management messages
 * =============================================================================
 */

/*
 *----------------------------------------------------------------------------- 
 *                  Process EPS Mobility Management NAS message
 *----------------------------------------------------------------------------- 
 */
static int
_nas_process_emm(
    char* buffer,
    int length,
    const EMM_msg* msg)
{
    int index = 0;
    const EsmMessageContainer* esm_container = NULL;

    printf("INFO\t: Process %s\n", emmMsgType(msg->header.message_type));
    index += snprintf(buffer + index, length - index, "%s (",
        emmMsgType(msg->header.message_type));

    switch (msg->header.message_type)
    {
    case ATTACH_REQUEST:
      esm_container = &msg->attach_request.esmmessagecontainer;
      index += _attach_request(buffer + index, length - index,
          &msg->attach_request);
      break;

    case ATTACH_ACCEPT:
      esm_container = &msg->attach_accept.esmmessagecontainer;
      index += _attach_accept(buffer + index, length - index,
          &msg->attach_accept);
      break;

    case ATTACH_REJECT:
      esm_container = &msg->attach_reject.esmmessagecontainer;
      index += _attach_reject(buffer + index, length - index,
          &msg->attach_reject);
      break;

    case ATTACH_COMPLETE:
      esm_container = &msg->attach_complete.esmmessagecontainer;
      index += _attach_complete(buffer + index, length - index,
          &msg->attach_complete);
      break;

    case DETACH_REQUEST:
      index += _detach_request(buffer + index, length - index,
          &msg->detach_request);
      break;

    case DETACH_ACCEPT:
      index += _detach_accept(buffer + index, length - index,
          &msg->detach_accept);
      break;

    case IDENTITY_REQUEST:
      index += _identity_request(buffer + index, length - index,
          &msg->identity_request);
      break;

    case IDENTITY_RESPONSE:
      index += _identity_response(buffer + index, length - index,
          &msg->identity_response);
      break;

    case AUTHENTICATION_REQUEST:
      index += _authentication_request(buffer + index, length - index,
          &msg->authentication_request);
      break;

    case AUTHENTICATION_RESPONSE:
      index += _authentication_response(buffer + index, length - index,
          &msg->authentication_response);
      break;

    case AUTHENTICATION_FAILURE:
      index += _authentication_failure(buffer + index, length - index,
          &msg->authentication_failure);
      break;

    case AUTHENTICATION_REJECT:
      index += _authentication_reject(buffer + index, length - index,
          &msg->authentication_reject);
      break;

    case SECURITY_MODE_COMMAND:
      index += _security_mode_command(buffer + index, length - index,
          &msg->security_mode_command);
      break;

    case SECURITY_MODE_COMPLETE:
      index += _security_mode_complete(buffer + index, length - index,
          &msg->security_mode_complete);
      break;

    case SECURITY_MODE_REJECT:
      index += _security_mode_reject(buffer + index, length - index,
          &msg->security_mode_reject);
      break;

    case EMM_STATUS:
      index += _emm_status(buffer + index, length - index,
          &msg->emm_status);
      break;

    default:
      printf("WARNING\t: %s - EMM NAS message is not valid (0x%x)\n",
          __FUNCTION__, msg->header.message_type);
      break;
    }

    index += snprintf(buffer + index, length - index, ")");

    /* Process ESM message container */
    if (esm_container) {
        index += _esm_message_container(buffer + index,
            length - index,
            esm_container);
    }

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *                              Process Attach Request
 *----------------------------------------------------------------------------- 
 */
static int
_attach_request(
    char* buffer,
    int length,
    const attach_request_msg* msg)
{
    int index = 0;

    /* EPS attach type */
    index += snprintf(buffer + index, length - index, "Type = %s",
        attachType(&msg->epsattachtype));
    /* NAS key set identifier */
    index += snprintf(buffer + index, length - index, ", KSI = ");
    index += nasKeySetIdentifier(buffer + index, length - index,
        &msg->naskeysetidentifier);
    /* EPS mobile identity */
    index += snprintf(buffer + index, length - index, ", ");
    index += epsIdentity(buffer + index, length - index,
        &msg->oldgutiorimsi);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *                              Process Attach Accept
 *----------------------------------------------------------------------------- 
 */
static int
_attach_accept(
    char* buffer,
    int length,
    const attach_accept_msg* msg)
{
    int index = 0;

#if 0
    /* T3412 timer value */
    index += snprintf(buffer + index, length - index, "T3412 = ");
    index += gprsTimer(buffer + index, length - index, &msg->t3412value);
    /* TAI list */
    index += snprintf(buffer + index, length - index, ", ");
    index += taiList(buffer + index, length - index, &msg->tailist);
#endif
    /* GUTI */
    if (msg->presencemask & ATTACH_ACCEPT_GUTI_PRESENT) {
        index += epsIdentity(buffer + index, length - index, &msg->guti);
    }

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Attach Reject
 *----------------------------------------------------------------------------- 
 */
static int
_attach_reject(
    char* buffer,
    int length,
    const attach_reject_msg* msg)
{
    int index = 0;

    /* EMM cause code */
    index += snprintf(buffer + index, length - index, "EmmCause = %s (%d)",
        emmCauseCode(msg->emmcause), msg->emmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Attach Complete
 *----------------------------------------------------------------------------- 
 */
static int
_attach_complete(
    char* buffer,
    int length,
    const attach_complete_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Identity Request
 *----------------------------------------------------------------------------- 
 */
static int
_identity_request(
    char* buffer,
    int length,
    const identity_request_msg* msg)
{
    int index = 0;

    /* Type of requested identity */
    index += snprintf(buffer + index, length - index, "Type = %s",
		      identityType(&msg->identitytype));

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Detach Request
 *----------------------------------------------------------------------------- 
 */
static int
_detach_request(
    char* buffer,
    int length,
    const detach_request_msg* msg)
{
    int index = 0;

    /* EPS attach type */
    index += snprintf(buffer + index, length - index, "Type = %s",
		      detachType(&msg->detachtype));
    /* NAS key set identifier */
    index += snprintf(buffer + index, length - index, ", KSI = ");
    index += nasKeySetIdentifier(buffer + index, length - index,
				 &msg->naskeysetidentifier);
    /* EPS mobile identity */
    index += snprintf(buffer + index, length - index, ", ");
    index += epsIdentity(buffer + index, length - index,
			 &msg->gutiorimsi);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Detach Accept
 *----------------------------------------------------------------------------- 
 */
static int
_detach_accept(
    char* buffer,
    int length,
    const detach_accept_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Identity Response
 *----------------------------------------------------------------------------- 
 */
static int
_identity_response(
    char* buffer,
    int length,
    const identity_response_msg* msg)
{
    int index = 0;

    /* Mobile identity */
    index += mobileIdentity(buffer + index, length - index,
			    &msg->mobileidentity);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Authentication Request
 *----------------------------------------------------------------------------- 
 */
static int
_authentication_request(
    char* buffer,
    int length,
    const authentication_request_msg* msg)
{
    int index = 0;

    /* NAS key set identifier ASME */
    index += snprintf(buffer + index, length - index, "KSIasme = ");
    index += nasKeySetIdentifier(buffer + index, length - index,
				 &msg->naskeysetidentifierasme);
    /* Authentication parameter RAND */
    index += snprintf(buffer + index, length - index, "\\nRAND = ");
    index += authenticationParameter(buffer + index, length - index,
				     &msg->authenticationparameterrand.rand);
    /* Authentication parameter AUTN */
    index += snprintf(buffer + index, length - index, ", AUTN = ");
    index += authenticationParameter(buffer + index, length - index,
				     &msg->authenticationparameterautn.autn);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Authentication Response
 *----------------------------------------------------------------------------- 
 */
static int
_authentication_response(
    char* buffer,
    int length,
    const authentication_response_msg* msg)
{
    int index = 0;

    /* Authentication response parameter */
    index += snprintf(buffer + index, length - index, "RES = ");
    index += authenticationParameter(buffer + index, length - index,
				     &msg->authenticationresponseparameter.res);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process Authentication Failure
 *----------------------------------------------------------------------------- 
 */
static int
_authentication_failure(
    char* buffer,
    int length,
    const authentication_failure_msg* msg)
{
    int index = 0;

    /* EMM cause */
    index += snprintf(buffer + index, length - index, "EmmCause = %s (%d)",
		      emmCauseCode(msg->emmcause), msg->emmcause);
    /* Authenticattion failure parameter */
    if (msg->presencemask & 
	AUTHENTICATION_FAILURE_AUTHENTICATION_FAILURE_PARAMETER_PRESENT) {
	index += snprintf(buffer + index, length - index, "AUTS = ");
	index += authenticationParameter(buffer + index, length - index,
					 &msg->authenticationfailureparameter.auts);
    }

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *			    Process Authentication Reject
 *----------------------------------------------------------------------------- 
 */
static int
_authentication_reject(
    char* buffer,
    int length,
    const authentication_reject_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *			    Process Security Mode Command
 *----------------------------------------------------------------------------- 
 */
static int
_security_mode_command(
    char* buffer,
    int length,
    const security_mode_command_msg* msg)
{
    int index = 0;

    /* Selected NAS ciphering algorithm */
    index += snprintf(buffer + index, length - index, "%s (%d)",
        nasCipheringAlgorithm(&msg->selectednassecurityalgorithms),
        msg->selectednassecurityalgorithms.typeofcipheringalgorithm);

   /* Selected NAS integrity algorithm */
    index += snprintf(buffer + index, length - index, ", %s (%d)",
        nasIntegrityAlgorithm(&msg->selectednassecurityalgorithms),
        msg->selectednassecurityalgorithms.typeofintegrityalgorithm);

    /* NAS key set identifier */
    index += snprintf(buffer + index, length - index, ", KSI = ");
    index += nasKeySetIdentifier(buffer + index, length - index,
        &msg->naskeysetidentifier);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *			    Process Security Mode Complete
 *----------------------------------------------------------------------------- 
 */
static int
_security_mode_complete(
    char* buffer,
    int length,
    const security_mode_complete_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *			    Process Security Mode Reject
 *----------------------------------------------------------------------------- 
 */
static int
_security_mode_reject(
    char* buffer,
    int length,
    const security_mode_reject_msg* msg)
{
    int index = 0;

    /* EMM cause code */
    index += snprintf(buffer + index, length - index, "EmmCause = %s (%d)",
		      emmCauseCode(msg->emmcause), msg->emmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				ESM message container
 *----------------------------------------------------------------------------- 
 */
static int
_esm_message_container(
    char* buffer,
    int length,
    const EsmMessageContainer* msg)
{
    int index = 0;
    int bytes;

    if (msg->esmmessagecontainercontents.length > 0)
    {
	nas_message_t nas_msg;
	memset(&nas_msg, 0, sizeof(nas_message_t));

	/* Decode ESM message container */
	bytes = nas_message_decode((char*)msg->esmmessagecontainercontents.value,
			&nas_msg, msg->esmmessagecontainercontents.length);
	if (bytes < 0) {
	    printf("ERROR\t: %s - Failed to decode ESM message container "
		   "(err=%d)\n", __FUNCTION__, bytes);
	    return (0);
	}

	index += snprintf(buffer + index, length - index, "\\n + ");

	/* Process EPS Session Management NAS message */
	index += _nas_process_esm(buffer + index, length - index,
				  &nas_msg.plain.esm);
    }

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process EMM Status
 *----------------------------------------------------------------------------- 
 */
static int
_emm_status(
    char* buffer,
    int length,
    const emm_status_msg* msg)
{
    int index = 0;

    /* EMM cause code */
    index += snprintf(buffer + index, length - index, "EmmCause = %s (%d)",
		      emmCauseCode(msg->emmcause), msg->emmcause);

    return (index);
}
/*
 * =============================================================================
 *	   Functions used to process EPS Session Management messages
 * =============================================================================
 */

/*
 *----------------------------------------------------------------------------- 
 *		    Process EPS Session MAnagement NAS message
 *----------------------------------------------------------------------------- 
 */
static int
_nas_process_esm(
    char* buffer,
    int length,
    const ESM_msg* msg)
{
    int index = 0;

    printf("INFO\t: Process %s\n", esmMsgType(msg->header.message_type));
    index += snprintf(buffer + index, length - index, "%s (pti=%d, ebi=%d",
        esmMsgType(msg->header.message_type),
        msg->header.procedure_transaction_identity,
        msg->header.eps_bearer_identity);

    switch (msg->header.message_type)
    {
    case PDN_CONNECTIVITY_REQUEST:
      index += _pdn_connectivity_request(buffer + index, length - index,
          &msg->pdn_connectivity_request);
      break;

    case PDN_CONNECTIVITY_REJECT:
      index += _pdn_connectivity_reject(buffer + index, length - index,
          &msg->pdn_connectivity_reject);
      break;

    case PDN_DISCONNECT_REQUEST:
      index += _pdn_disconnect_request(buffer + index, length - index,
          &msg->pdn_disconnect_request);
      break;

    case PDN_DISCONNECT_REJECT:
      index += _pdn_disconnect_reject(buffer + index, length - index,
          &msg->pdn_disconnect_reject);
      break;

    case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST:
      index += _activate_default_eps_bearer_context_request(
          buffer + index, length - index,
          &msg->activate_default_eps_bearer_context_request);
      break;

    case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT:
      index += _activate_default_eps_bearer_context_accept(
          buffer + index, length - index,
          &msg->activate_default_eps_bearer_context_accept);
      break;

    case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT:
      index += _activate_default_eps_bearer_context_reject(
          buffer + index, length - index,
          &msg->activate_default_eps_bearer_context_reject);
      break;

    case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST:
      index += _activate_dedicated_eps_bearer_context_request(
          buffer + index, length - index,
          &msg->activate_dedicated_eps_bearer_context_request);
      break;

    case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT:
      index += _activate_dedicated_eps_bearer_context_accept(
          buffer + index, length - index,
          &msg->activate_dedicated_eps_bearer_context_accept);
      break;

    case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT:
      index += _activate_dedicated_eps_bearer_context_reject(
          buffer + index, length - index,
          &msg->activate_dedicated_eps_bearer_context_reject);
      break;

    case DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST:
      index += _deactivate_eps_bearer_context_request(buffer + index,
          length - index,
          &msg->deactivate_eps_bearer_context_request);
      break;

    case DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT:
      index += _deactivate_eps_bearer_context_accept(buffer + index,
          length - index,
          &msg->deactivate_eps_bearer_context_accept);
      break;

    case ESM_STATUS:
      index += _esm_status(buffer + index, length - index,
          &msg->esm_status);
      break;

    default:
      printf("WARNING\t: %s - ESM NAS message is not valid (0x%x)\n",
          __FUNCTION__, msg->header.message_type);
      break;
    }

    index += snprintf(buffer + index, length - index, ")");

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *                          Process PDN Connectivity Request
 *----------------------------------------------------------------------------- 
 */
static int
_pdn_connectivity_request(
    char* buffer,
    int length,
    const pdn_connectivity_request_msg* msg)
{
    int index = 0;

    /* PDN request type and PDN type */
    index += snprintf(buffer + index, length - index,
        ", RequestType = %s, PdnType = %s",
        requestType(&msg->requesttype),
        pdnType(&msg->pdntype));
    /* Access Point Name */
    if (msg->presencemask & PDN_CONNECTIVITY_REQUEST_ACCESS_POINT_NAME_PRESENT)
    {
        index += snprintf(buffer + index, length - index, ", APN = %s",
            (char*)msg->accesspointname.accesspointnamevalue.value);
    }

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *                          Process PDN Connectivity Reject
 *----------------------------------------------------------------------------- 
 */
static int
_pdn_connectivity_reject(
    char* buffer,
    int length,
    const pdn_connectivity_reject_msg* msg)
{
    int index = 0;

    /* ESM cause code */
    index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
        esmCauseCode(msg->esmcause), msg->esmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *			    Process PDN Disconnect Request
 *----------------------------------------------------------------------------- 
 */
static int
_pdn_disconnect_request(
    char* buffer,
    int length,
    const pdn_disconnect_request_msg* msg)
{
    int index = 0;

    /* Linked EPS bearer identity */
    index += snprintf(buffer + index, length - index, ", Linked EBI = %d",
        msg->linkedepsbeareridentity);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *                          Process PDN Disconnect Reject
 *----------------------------------------------------------------------------- 
 */
static int
_pdn_disconnect_reject(
    char* buffer,
    int length,
    const pdn_disconnect_reject_msg* msg)
{
    int index = 0;

    /* ESM cause code */
    index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
        esmCauseCode(msg->esmcause), msg->esmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *              Process Activate Default EPS Bearer Context Request
 *----------------------------------------------------------------------------- 
 */
static int
_activate_default_eps_bearer_context_request(
    char* buffer,
    int length,
    const activate_default_eps_bearer_context_request_msg* msg)
{
    int index = 0;

    /* Access Point Name */
    index += snprintf(buffer + index, length - index, ", APN = %s",
        (char*)msg->accesspointname.accesspointnamevalue.value);

    /* PDN address */
    index += snprintf(buffer + index, length - index, ", PDN addr = ");
    index += pdnAddress(buffer + index, length - index, &msg->pdnaddress);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Activate Default EPS Bearer Context Accept
 *----------------------------------------------------------------------------- 
 */
static int
_activate_default_eps_bearer_context_accept(
    char* buffer,
    int length,
    const activate_default_eps_bearer_context_accept_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Activate Default EPS Bearer Context Reject
 *----------------------------------------------------------------------------- 
 */
static int
_activate_default_eps_bearer_context_reject(
    char* buffer,
    int length,
    const activate_default_eps_bearer_context_reject_msg* msg)
{
    int index = 0;

    /* ESM cause code */
    index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
        esmCauseCode(msg->esmcause), msg->esmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Activate Dedicated EPS Bearer Context Request
 *----------------------------------------------------------------------------- 
 */
static int
_activate_dedicated_eps_bearer_context_request(
    char* buffer,
    int length,
    const activate_dedicated_eps_bearer_context_request_msg* msg)
{
    int index = 0;

    /* Linked EPS bearer identity */
    index += snprintf(buffer + index, length - index, ", Linked EBI = %d",
		      msg->linkedepsbeareridentity);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Activate Dedicated EPS Bearer Context Accept
 *----------------------------------------------------------------------------- 
 */
static int
_activate_dedicated_eps_bearer_context_accept(
    char* buffer,
    int length,
    const activate_dedicated_eps_bearer_context_accept_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Activate Dedicated EPS Bearer Context Reject
 *----------------------------------------------------------------------------- 
 */
static int
_activate_dedicated_eps_bearer_context_reject(
    char* buffer,
    int length,
    const activate_dedicated_eps_bearer_context_reject_msg* msg)
{
    int index = 0;

    /* ESM cause code */
    index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
        esmCauseCode(msg->esmcause), msg->esmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Deactivate EPS Bearer Context Request
 *----------------------------------------------------------------------------- 
 */
static int _deactivate_eps_bearer_context_request(
    char* buffer,
    int length,
    const deactivate_eps_bearer_context_request_msg* msg)
{
    int index = 0;

    /* ESM cause code */
    index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
        esmCauseCode(msg->esmcause), msg->esmcause);

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *		Process Deactivate EPS Bearer Context Accept
 *----------------------------------------------------------------------------- 
 */
static int
_deactivate_eps_bearer_context_accept(
    char* buffer,
    int length,
    const deactivate_eps_bearer_context_accept_msg* msg)
{
    int index = 0;

    return (index);
}

/*
 *----------------------------------------------------------------------------- 
 *				Process ESM Status
 *----------------------------------------------------------------------------- 
 */
static int
_esm_status(
    char* buffer,
    int length,
    const esm_status_msg* msg)
{
    int index = 0;

    /* ESM cause code */
    index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
        esmCauseCode(msg->esmcause), msg->esmcause);

    return (index);
}