/************************************************************************************
* This is the header file for the memory and message module.
*
* Author(s): BPPED1
*
* (c) Copyright 2004, Freescale, Inc.  All rights reserved.
*
* Freescale Confidential Proprietary
* Digianswer Confidential
*
* No part of this document must be reproduced in any form - including copied,
* transcribed, printed or by any electronic means - without specific written
* permission from Freescale.
*
* Last Inspected:
* Last Tested:
*
* Source Safe revision history (Do not edit manually) 
*   $Date: 22-04-04 13:54 $
*   $Author: Bpped1 $
*   $Revision: 23 $
*   $Workfile: PhyMacMsg.h $
************************************************************************************/

#ifndef _PHY_MAC_MSG_H_
#define _PHY_MAC_MSG_H_

#include "MacPhy.h"
#include "NwkMacInterface.h"
#ifndef MM_DEBUG
#include "MsgSystem.h"
#endif // MM_DEBUG

/************************************************************************************
*************************************************************************************
* Public macros
*************************************************************************************
************************************************************************************/

#ifndef MM_DEBUG

void *MM_AllocFast(void);

#else

  // Override previous defines
#undef MSG_AllocType
#define MSG_AllocType(type) MM_AllocDebug(sizeof(type), __FILE__, (uint16_t)(__LINE__))

#undef MSG_Alloc
#define MSG_Alloc(size) MM_AllocDebug(size, __FILE__, (uint16_t)(__LINE__))

#undef MSG_Send
#define MSG_Send(sap, msg) (sap##_SapHandlerDebug((void *)(msg), __FILE__, (uint16_t)(__LINE__)))

  // Not public functions any longer
#define MM_Alloc(size) MM_AllocDebug(size, __FILE__, (uint16_t)(__LINE__))
#define MM_AllocPool(pools, size) MM_AllocPoolDebug(pools, size, __FILE__, (uint16_t)(__LINE__))
#define MM_AllocFast() MM_AllocFastDebug(__FILE__, (uint16_t)(__LINE__))

#undef MSG_Queue
#define MSG_Queue(anchor, element) { List_AddTail((anchor), (element)); (((listHeader_t *)(element))-1)->queueInfo = "Queued in " #anchor ; }

#endif // MM_DEBUG

/************************************************************************************
*************************************************************************************
* Public type definitions
*************************************************************************************
************************************************************************************/

  // This struct is used privately but must be declared
  // here in order for the anchor_t struct to work.
  // The struct is used in memory blocks for linking them
  // in single chained lists. The struct is embedded in
  // list elements, and transparent to the users. 
#ifdef MM_DEBUG

typedef struct listHeader_tag {
  struct listHeader_tag *pNext;
  struct pools_tag *pParentPool;
  uint8_t *fileName;
  uint16_t lineNumber;
  uint8_t *queueInfo;
} listHeader_t;

  // List anchor with head and tail elements. Used 
  // for both memory pools and message queues.
typedef struct anchor_tag {
  listHeader_t *pHead;
  listHeader_t *pTail;
  uint8_t numElements;
} anchor_t;

typedef struct poolStat_tag {
  uint8_t numBlocks;
  uint8_t allocatedBlocks;
  uint8_t allocatedBlocksPeak;
  uint16_t allocationFailures;
} poolStat_t;

typedef struct pools_tag {
  anchor_t anchor; // MUST be first element in pools_t struct
  //void *pEndAddress;
  uint8_t nextBlockSize;
  uint8_t blockSize;
  poolStat_t poolStat;
} pools_t;

typedef struct poolInfo_tag {
  uint8_t poolSize;
  uint8_t blockSize;
  uint8_t nextBlockSize;
} poolInfo_t;

typedef anchor_t msgQueue_t;

#include "MsgSystem.h"

typedef struct block0_tag {
  listHeader_t  listHeader;
  uint8_t       data[mMmBlockSize0_c];
} block0_t;

#if gMmNumPools_c > 1
typedef struct block1_tag {
  listHeader_t  listHeader;
  uint8_t       data[mMmBlockSize1_c];
} block1_t;
#endif // gMmNumPools_c > 1

#if gMmNumPools_c > 2
typedef struct block2_tag {
  listHeader_t  listHeader;
  uint8_t       data[mMmBlockSize2_c];
} block2_t;
#endif // gMmNumPools_c > 2

#if gMmNumPools_c > 3
typedef struct block3_tag {
  listHeader_t  listHeader;
  uint8_t       data[mMmBlockSize3_c];
} block3_t;
#endif // gMmNumPools_c > 3

typedef struct macHeap_tag {
  block0_t block0[gMmPoolSize0_c];
#if gMmNumPools_c > 1
  block1_t block1[gMmPoolSize1_c];
#if (gMmNumPools_c > 2) && (gMmPoolSize2_c != 0)
  block2_t block2[gMmPoolSize2_c];
#if gMmNumPools_c > 3
  block3_t block3[gMmPoolSize3_c];
#endif // gMmNumPools_c > 3
#endif // gMmNumPools_c > 2
#endif // gMmNumPools_c > 1
} macHeap_t;

#endif // MM_DEBUG


#if gBigMsgsMacOnly_d
void MM_SetPrivatePool(privatePoolState_t state); // Parameters: gMmDisablePrivatePool_c, or gMmEnablePrivatePool_c
#else
#define MM_SetPrivatePool(state)
#endif // gBigMsgsMacOnly_d

#ifdef MM_DEBUG
extern void *MM_AllocDebug(uint8_t size, uint8_t *fileName, uint16_t lineNumber);
extern void *MM_AllocPoolDebug(pools_t *pPools, uint8_t size, uint8_t *fileName, uint16_t lineNumber);
extern void *MM_AllocFastDebug(uint8_t *fileName, uint16_t lineNumber);

extern void    MEM_MLME_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t MLME_NWK_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern void    MLME_MEM_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t MCPS_NWK_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t NWK_MLME_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t NWK_MCPS_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t MEM_ASP_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t ASP_APP_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);
extern uint8_t APP_ASP_SapHandlerDebug(void *pMsg, uint8_t *fileName, uint16_t lineNumber);

#endif // MM_DEBUG

#endif /* _PHY_MAC_MSG_H_ */
