/**************************************************************************************************
  Filename:       nwk.h
  Revised:        $Date: 2008-12-01 11:58:33 -0800 (Mon, 01 Dec 2008) $
  Revision:       $Revision: 18551 $
  Author:         $Author: lfriedman $

  Description:    This header file supports the SimpliciTI network layer.

  Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved.

  IMPORTANT: Your use of this Software is limited to those specific rights granted under
  the terms of a software license agreement between the user who downloaded the software,
  his/her employer (which must be your employer) and Texas Instruments Incorporated (the
  "License"). You may not use this Software unless you agree to abide by the terms of the
  License. The License limits your use, and you acknowledge, that the Software may not be
  modified, copied or distributed unless embedded on a Texas Instruments microcontroller
  or used solely and exclusively in conjunction with a Texas Instruments radio frequency
  transceiver, which is integrated into your product. Other than for the foregoing purpose,
  you may not use, reproduce, copy, prepare derivative works of, modify, distribute,
  perform, display or sell this Software and/or its documentation for any purpose.

  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS”
  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY
  WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
  IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE
  THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY
  INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
  DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY
  THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

  Should you have any questions regarding your right to use this Software,
  contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/

#ifndef NWK_H
#define NWK_H


/* well known ports*/
#define SMPL_PORT_PING          0x01
#define SMPL_PORT_LINK          0x02
#define SMPL_PORT_JOIN          0x03
#define SMPL_PORT_SECURITY      0x04
#define SMPL_PORT_FREQ          0x05
#define SMPL_PORT_MGMT          0x06

#define SMPL_PORT_NWK_BCAST     0x1F
#define SMPL_PORT_USER_BCAST    0x3F

/* Unconnected User Datagram Link ID */
#define SMPL_LINKID_USER_UUD    ((linkID_t) ~0)

#define PORT_BASE_NUMBER        0x20

/* Reserve the top of the User port namespace below the broadcast
 * address for static allocation.
 */
#define PORT_USER_STATIC_NUM    1
#define SMPL_PORT_STATIC_MAX    0x3E
#define SMPL_PORT_USER_MAX      (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM)


/* to check connection info sanity */
#define CHK_RX   0
#define CHK_TX   1

/* return types for validating a reply frame */
#define SMPL_MY_REPLY    0
#define SMPL_A_REPLY     1
#define SMPL_NOT_REPLY   2

/* when allocating local Rx port it depends on whether the allocation
 * is being done as a result of a link or a link reply
 */
#define LINK_SEND   1
#define LINK_REPLY  2

#define  CONNSTATE_FREE       (0x00)
#define  CONNSTATE_JOINED     (0x01)
#define  CONNSTATE_CONNECTED  (0x02)

typedef struct
{
  volatile uint8_t     connState;
           uint8_t     hops2target;
#ifdef APP_AUTO_ACK
  volatile uint8_t     ackTID;
#endif
           uint8_t     peerAddr[NET_ADDR_SIZE];
           rxMetrics_t sigInfo;
           uint8_t     portRx;
           uint8_t     portTx;
           linkID_t    thisLinkID;
#ifdef SMPL_SECURE
           uint32_t    connTxCTR;
           uint32_t    connRxCTR;
#endif
} connInfo_t;

/****************************************************************************************
 *                         Application Payload TID support
 *
 * Sometimes the receiving application uses a payload TID to determine if either it
 * missed frames (received TID > (last-seen TID+1)) or is seeing a duplicate (received
 * TID <= last-seen TID). Typically the TID simply increments for each successive frame.
 * But when the count wraps there is a problem. The received TID should always be one
 * more than the last TID. If it's equal, it's a duplicate. If it's less it's late. If
 * it's one more it's the one we expect. If it's more than 1 more then we missed frames.
 * Simple increments work for the wrap arithmetically. If the received TID is 0 and the last
 * seen ID is the biggest number in the world -- 0xFF... depending on type we can detect
 * the wrap. But if the receiver misses the 0 TID value for any reason or the biggest
 * number in the world TID is missed then susbequent testing for missed or duplicate
 * frames can get confused. We resolve this by allowing some leeway in the wrap testing.
 * this testing is assisted by the following macros. Setting TID_VALID_WINDOW to 0
 * will enforce a no leniency policy. In this case you'd better not miss either the
 * biggest number or the 0. The CHECK_TID_WRAP macro is only needed if the received
 * TID is less than the last-seen TID. The DUP_TID_AFTER_WRAP macro is only needed if the
 * received TID is greater than 1 more than the last-seen TID.
 ***************************************************************************************/
#define MAX_APT           ((appPTid_t)~0)    /* max value of application payload TID type */
#define TID_VALID_WINDOW  2                  /* window around max and 0 */

#define CHECK_TID_WRAP(lastTID, newTID)   ((lastTID >= (MAX_APT - TID_VALID_WINDOW)) &&  \
                                           (newTID <= TID_VALID_WINDOW)                  \
                                          )
#define DUP_TID_AFTER_WRAP(lastTID, newTID)     ((newTID >= (MAX_APT - TID_VALID_WINDOW)) &&  \
                                                 (lastTID <= TID_VALID_WINDOW)                  \
                                                )

/* prototypes */
smplStatus_t  nwk_nwkInit(uint8_t (*)(linkID_t));
connInfo_t   *nwk_getNextConnection(void);
void          nwk_freeConnection(connInfo_t *);
uint8_t       nwk_getNextClientPort(void);
connInfo_t   *nwk_getConnInfo(linkID_t port);
connInfo_t   *nwk_isLinkDuplicate(uint8_t *, uint8_t);
uint8_t       nwk_findAddressMatch(mrfiPacket_t *);
smplStatus_t  nwk_checkConnInfo(connInfo_t *, uint8_t);
uint8_t       nwk_isConnectionValid(mrfiPacket_t *, linkID_t *);
uint8_t       nwk_allocateLocalRxPort(uint8_t, connInfo_t *);
uint8_t       nwk_isValidReply(mrfiPacket_t *, uint8_t, uint8_t, uint8_t);
connInfo_t   *nwk_findPeer(addr_t *, uint8_t);
smplStatus_t  nwk_NVObj(ioctlAction_t, ioctlNVObj_t *);


uint8_t       nwk_checkAppMsgTID(appPTid_t, appPTid_t);
void          nwk_getNumObjectFromMsg(void *, void *, uint8_t);
void          nwk_putNumObjectIntoMsg(void *, void *, uint8_t);
#ifdef ACCESS_POINT
sfInfo_t     *nwk_getSFInfoPtr(void);
#ifdef AP_IS_DATA_HUB
uint8_t       nwk_saveJoinedDevice(mrfiPacket_t *);
connInfo_t   *nwk_findAlreadyJoined(mrfiPacket_t *);
#endif
#endif


#endif
