/*----------------------------------------------------------------------------*
 *                                                                            *
 *                             n w - g t p v 2 u                              *
 *    G P R S   T u n n e l i n g    P r o t o c o l   v 2 u    S t a c k     *
 *                                                                            *
 *                                                                            *
 * Copyright (c) 2010-2011 Amit Chawre                                        *
 * All rights reserved.                                                       *
 *                                                                            *
 * Redistribution and use in source and binary forms, with or without         *
 * modification, are permitted provided that the following conditions         *
 * are met:                                                                   *
 *                                                                            *
 * 1. Redistributions of source code must retain the above copyright          *
 *    notice, this list of conditions and the following disclaimer.           *
 * 2. Redistributions in binary form must reproduce the above copyright       *
 *    notice, this list of conditions and the following disclaimer in the     *
 *    documentation and/or other materials provided with the distribution.    *
 * 3. The name of the author may not be used to endorse or promote products   *
 *    derived from this software without specific prior written permission.   *
 *                                                                            *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR       *
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.    *
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,           *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT   *
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY      *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT        *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF   *
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.          *
 *----------------------------------------------------------------------------*/

#ifndef __NW_GTPV1U_MSG_H__
#define __NW_GTPV1U_MSG_H__

#include "NwTypes.h"
#include "NwGtpv1u.h"

/**
 * @file NwGtpv1uMsg.h
 * @brief This file defines APIs for to build new outgoing gtpv1u messages and to parse incoming messages.
*/

#ifdef __cplusplus
extern "C" {
#endif

/*--------------------------------------------------------------------------*
 *   G T P V 2 C     I E    D A T A - T Y P E      D E F I N I T I O N S    *
 *--------------------------------------------------------------------------*/

#pragma pack(1)

typedef struct NwGtpv1uIeTv1 {
  uint8_t  t;
  uint8_t  v;
} NwGtpv1uIeTv1T;

typedef struct NwGtpv1uIeTv2 {
  uint8_t  t;
  uint8_t  v;
} NwGtpv1uIeTv2T;

typedef struct NwGtpv1uIeTv4 {
  uint8_t  t;
  uint32_t  v;
} NwGtpv1uIeTv4T;

typedef struct NwGtpv1uIeTlv {
  uint8_t  t;
  uint16_t l;
} NwGtpv1uIeTlvT;

#pragma pack()


/**
 * Allocate a GPDU gtpv1u message.
 *
 * @param[in] hGtpuStackHandle : gtpv1u stack handle.
 * @param[in] teidPresent : TEID is present flag.
 * @param[in] teid : TEID for this message.
 * @param[in] seqNum : Sequence number for this message.
 * @param[out] phMsg : Pointer to message handle.
 */

NwGtpv1uRcT
nwGtpv1uMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
                NW_IN uint8_t     seqNumFlag,
                NW_IN uint8_t     npduNumFlag,
                NW_IN uint8_t     extHdrFlag,
                NW_IN uint8_t     msgType,
                NW_IN uint8_t     teid,
                NW_IN uint16_t    seqNum,
                NW_IN uint8_t     npduNum,
                NW_IN uint8_t     nextExtHeader,
                NW_OUT NwGtpv1uMsgHandleT *phMsg);


/**
 * Allocate a gtpv1u message.
 *
 * @param[in] hGtpuStackHandle : gtpv1u stack handle.
 * @param[in] teid : TEID for this message.
 * @param[in] seqNumFlag : Sequence number flag for this message.
 * @param[in] seqNum : Sequence number for this message.
 * @param[in] pTpdu: T-PDU for this message.
 * @param[in] tpduLength: T-PDU length for this message.
 * @param[out] phMsg : Pointer to message handle.
 */

NwGtpv1uRcT
nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
                    NW_IN uint32_t    teid,
                    NW_IN uint8_t     seqNumFlag,
                    NW_IN uint16_t    seqNum,
                    NW_IN uint8_t*    tpdu,
                    NW_IN uint16_t    tpduLength,
                    NW_IN uint32_t    tpduOffset,
                    NW_OUT NwGtpv1uMsgHandleT *phMsg);

/**
 * Allocate a gtpv1u message from another gtpv1u message.
 *
 * @param[in] hGtpuStackHandle : gtpv1u stack handle.
 * @param[out] hMsg : Handle to input message.
 * @param[out] phMsg : Pointer to message handle.
 */

NwGtpv1uRcT
nwGtpv1uMsgFromMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
                       NW_IN NwGtpv1uMsgHandleT hMsg,
                       NW_OUT NwGtpv1uMsgHandleT *phMsg);
/**
 * Allocate a gtpv1u message from data buffer.
 *
 * @param[in] hGtpuStackHandle : gtpv1u stack handle.
 * @param[in] pBuf: Buffer to be copied in this message.
 * @param[in] bufLen: Buffer length to be copied in this message.
 * @param[out] phMsg : Pointer to message handle.
 */

NwGtpv1uRcT
nwGtpv1uMsgFromBufferNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
                          NW_IN uint8_t* pBuf,
                          NW_IN uint32_t bufLen,
                          NW_OUT NwGtpv1uMsgHandleT *phMsg);

/**
 * Free a gtpv1u message.
 *
 * @param[in] hGtpuStackHandle : gtpv1u stack handle.
 * @param[in] hMsg : Message handle.
 */

NwGtpv1uRcT
nwGtpv1uMsgDelete( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
                   NW_IN NwGtpv1uMsgHandleT hMsg);

/**
 * Set TEID for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 * @param[in] teid: TEID value.
 */

NwGtpv1uRcT
nwGtpv1uMsgSetTeid(NW_IN NwGtpv1uMsgHandleT hMsg, uint32_t teid);

/**
 * Set TEID present flag for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 * @param[in] teidPesent: Flag boolean value.
 */

NwGtpv1uRcT
nwGtpv1uMsgSetTeidPresent(NW_IN NwGtpv1uMsgHandleT hMsg, NwBoolT teidPresent);

/**
 * Set sequence for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 * @param[in] seqNum: Flag boolean value.
 */

NwGtpv1uRcT
nwGtpv1uMsgSetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg, uint32_t seqNum);

/**
 * Get TEID present for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 */

uint32_t
nwGtpv1uMsgGetTeid(NW_IN NwGtpv1uMsgHandleT hMsg);

/**
 * Get TEID present for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 */

NwBoolT
nwGtpv1uMsgGetTeidPresent(NW_IN NwGtpv1uMsgHandleT hMsg);

/**
 * Get sequence number for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 */

uint32_t
nwGtpv1uMsgGetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg);

/**
 * Get tpdu for gtpv1u message.
 *
 * @param[in] hMsg : Message handle.
 * @param[inout] pTpduBuf : Buffer to copy the T-PDU.
 * @param[out] hMsg : T-PDU length.
 */

uint32_t
nwGtpv1uMsgGetTpdu(NW_IN NwGtpv1uMsgHandleT hMsg, uint8_t* pTpduBuf, uint32_t* pTpduLength);

uint8_t*
nwGtpv1uMsgGetTpduHandle(NW_IN NwGtpv1uMsgHandleT hMsg);

uint32_t
nwGtpv1uMsgGetTpduLength(NW_IN NwGtpv1uMsgHandleT hMsg);

/**
 * Add a gtpv1u information element of length 1 to gtpv1u mesasge.
 *
 * @param[in] hMsg : Handle to gtpv1u message.
 * @param[in] type : IE type.
 * @param[in] value : IE value.
 */

NwGtpv1uRcT
nwGtpv1uMsgAddIeTV1(NW_IN NwGtpv1uMsgHandleT hMsg,
                    NW_IN uint8_t       type,
                    NW_IN uint8_t       value);


/**
 * Add a gtpv1u information element of length 2 to gtpv1u mesasge.
 *
 * @param[in] hMsg : Handle to gtpv1u message.
 * @param[in] type : IE type.
 * @param[in] value : IE value.
 */

NwGtpv1uRcT
nwGtpv1uMsgAddIeTV2(NW_IN NwGtpv1uMsgHandleT hMsg,
                    NW_IN uint8_t       type,
                    NW_IN uint16_t      length,
                    NW_IN uint16_t      value);


/**
 * Add a gtpv1u information element of length 4 to gtpv1u mesasge.
 *
 * @param[in] hMsg : Handle to gtpv1u message.
 * @param[in] type : IE type.
 * @param[in] value : IE value.
 */

NwGtpv1uRcT
nwGtpv1uMsgAddIeTV4(NW_IN NwGtpv1uMsgHandleT hMsg,
                    NW_IN uint8_t       type,
                    NW_IN uint16_t      length,
                    NW_IN uint32_t      value);


/**
 * Add a gtpv1u information element of variable length to gtpv1u mesasge.
 *
 * @param[in] hMsg : Handle to gtpv1u message.
 * @param[in] type : IE type.
 * @param[in] length : IE length.
 * @param[in] value : IE value.
 */

NwGtpv1uRcT
nwGtpv1uMsgAddIe(NW_IN NwGtpv1uMsgHandleT hMsg,
                 NW_IN uint8_t       type,
                 NW_IN uint16_t      length,
                 NW_IN uint8_t*      pVal);

/**
 * Dump the contents of gtpv1u mesasge.
 *
 * @param[in] hMsg : Handle to gtpv1u message.
 * @param[in] fp: Pointer to output file.
 */

NwGtpv1uRcT
nwGtpv1uMsgHexDump(NwGtpv1uMsgHandleT hMsg, FILE* fp);

uint32_t
nwGtpv1uMsgGetMsgType(NW_IN NwGtpv1uMsgHandleT hMsg);

#ifdef __cplusplus
}
#endif

#endif /* __NW_TYPES_H__ */


/*--------------------------------------------------------------------------*
 *                      E N D     O F    F I L E                            *
 *--------------------------------------------------------------------------*/