/***************************************************************************** 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); }