#ifndef	_NMIMP_H_
#define	_NMIMP_H_
/*
 * nmimp.h: Definitions of IMP data marshaling/unmarshaling stuff.
 *
 * Bruce Nelson, interWAVE, 08/16/95.
 */

#include "iwtypes.h"
#include "nmtypes.h"
#include "nmstatus.h"

/* IMP agent IP port number.
 */
#define	IMP_PORT		2112

/* IMP message types, i.e., operation codes.  Notice that response codes are
 * the same as request codes, but with the "response bit" turned on.  If the
 * NOBJ bit is on, the request/response does not apply to an object, but to an
 * entire agent and/or management application. 
 */
#define	IMP_MSG_UNDEFINED	0x000
#define	IMP_MSG_RESP_BIT	0x040
#define	IMP_MSG_NOBJ_BIT	0x080
#define	IMP_MSG_GET_REQ		0x001
#define	IMP_MSG_GET_RESP	0x041
#define	IMP_MSG_SET_REQ		0x002
#define	IMP_MSG_SET_RESP	0x042
#define	IMP_MSG_ACTION_REQ	0x003
#define	IMP_MSG_ACTION_RESP	0x043
#define	IMP_MSG_CREATE_REQ	0x004
#define	IMP_MSG_CREATE_RESP	0x044
#define	IMP_MSG_DELETE_REQ	0x005
#define	IMP_MSG_DELETE_RESP	0x045
#define	IMP_MSG_CONTENTS_REQ	0x006
#define	IMP_MSG_CONTENTS_RESP	0x046
#define	IMP_MSG_VALIDATE_REQ	0x007
#define	IMP_MSG_VALIDATE_RESP	0x047
#define	IMP_MSG_GETSEEK_REQ	0x008
#define	IMP_MSG_GETSEEK_RESP	0x048
#define	IMP_MSG_UNBUSY_REQ	0x009
#define	IMP_MSG_UNBUSY_RESP	0x049
#define	IMP_MSG_EVENT_IND	0x04a

#define	IMP_MSG_CREATE_FWD	0x03a
#define	IMP_MSG_DELETE_FWD	0x039

/* Definitions of IMP type masks: upper five bits of tag byte.
 */
#define	IMP_TYPE_MASK		0x0f8
#define	IMP_TYPE_NULL		0x080
#define	IMP_TYPE_UINT		0x088
#define	IMP_TYPE_SINT		0x090
#define	IMP_TYPE_CHAR_STRING	0x098
#define	IMP_TYPE_OBJECT_ID	0x0a0
#define	IMP_TYPE_CLASS_ID	0x0a8
#define	IMP_TYPE_ATTR_ID	0x0b0
#define	IMP_TYPE_EVENT_ID	0x0b8
#define	IMP_TYPE_ACTION_ID	0x0c0
#define	IMP_TYPE_STATUS_CODE	0x0c8
#define	IMP_TYPE_END_OF_MSG	0x0d0
#define	IMP_TYPE_USER_ID	0x0d8
#define	IMP_TYPE_COMPARATOR	0x0e0
#define	IMP_TYPE_APP_ADDR	0x0e8
#define	IMP_TYPE_LENGTH		0x0f0
#define	IMP_TYPE_IX_UINT	0x008
#define	IMP_TYPE_IX_SINT	0x010

/* Fixed size of an IMP marshaled length field.
 */
#define	IMP_TYPE_LENGTH_MBYTES	3

/* Definitions of IMP array masks: bit two of tag byte.
 */
#define	IMP_ARRAY_MASK		0x004
#define	IMP_ARRAY_TRUE		0x004
#define	IMP_ARRAY_FALSE		0x000

/* Definitions of array types and a mask to select both the type field and
 * the array bit.  The marshal/unmarshal functions need to check for both
 * correct type value and correct array bit.
 */
#define	IMP_ARRAY_TYPE_MASK	(IMP_TYPE_MASK | IMP_ARRAY_MASK)
#define	IMP_ARRAY_UINT		(IMP_TYPE_UINT | IMP_ARRAY_TRUE)
#define	IMP_ARRAY_SINT		(IMP_TYPE_SINT | IMP_ARRAY_TRUE)
#define	IMP_ARRAY_CHAR_STRING	(IMP_TYPE_CHAR_STRING | IMP_ARRAY_TRUE)
#define	IMP_ARRAY_OBJECT_ID	(IMP_TYPE_OBJECT_ID | IMP_ARRAY_TRUE)
#define	IMP_ARRAY_APP_ADDR	(IMP_TYPE_APP_ADDR | IMP_ARRAY_TRUE)
#define	IMP_ARRAY_IX_UINT	(IMP_TYPE_IX_UINT | IMP_ARRAY_TRUE)
#define	IMP_ARRAY_IX_SINT	(IMP_TYPE_IX_SINT | IMP_ARRAY_TRUE)

/* Definitions of IMP unit masks: low two bits of tag byte.
 */
#define	IMP_UNIT_MASK		0x003
#define	IMP_UNIT_1		0x000
#define	IMP_UNIT_2		0x001
#define	IMP_UNIT_3		0x002
#define	IMP_UNIT_4		0x003

/* Definitions of IMP tag byte values.
 */
#define	IMP_TAG_NULL \
	(u8)(IMP_TYPE_NULL | IMP_ARRAY_FALSE | IMP_UNIT_1)
#define	IMP_TAG_UINT_1 \
	(u8)(IMP_TYPE_UINT | IMP_ARRAY_FALSE | IMP_UNIT_1)
#define	IMP_TAG_SINT_1 \
	(u8)(IMP_TYPE_SINT | IMP_ARRAY_FALSE | IMP_UNIT_1)
#define	IMP_TAG_UINT_2 \
	(u8)(IMP_TYPE_UINT | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_SINT_2 \
	(u8)(IMP_TYPE_SINT | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_UINT_4 \
	(u8)(IMP_TYPE_UINT | IMP_ARRAY_FALSE | IMP_UNIT_4)
#define	IMP_TAG_SINT_4 \
	(u8)(IMP_TYPE_SINT | IMP_ARRAY_FALSE | IMP_UNIT_4)
#define	IMP_TAG_UARRAY_1 \
	(u8)(IMP_TYPE_UINT | IMP_ARRAY_TRUE | IMP_UNIT_1)
#define	IMP_TAG_SARRAY_1 \
	(u8)(IMP_TYPE_SINT | IMP_ARRAY_TRUE | IMP_UNIT_1)
#define	IMP_TAG_UARRAY_2 \
	(u8)(IMP_TYPE_UINT | IMP_ARRAY_TRUE | IMP_UNIT_2)
#define	IMP_TAG_SARRAY_2 \
	(u8)(IMP_TYPE_SINT | IMP_ARRAY_TRUE | IMP_UNIT_2)
#define	IMP_TAG_UARRAY_4 \
	(u8)(IMP_TYPE_UINT | IMP_ARRAY_TRUE | IMP_UNIT_4)
#define	IMP_TAG_SARRAY_4 \
	(u8)(IMP_TYPE_SINT | IMP_ARRAY_TRUE | IMP_UNIT_4)
#define	IMP_TAG_CHAR_STRING \
	(u8)(IMP_TYPE_CHAR_STRING | IMP_ARRAY_TRUE | IMP_UNIT_1)
#define	IMP_TAG_OBJECT_ID \
	(u8)(IMP_TYPE_OBJECT_ID | IMP_ARRAY_TRUE | IMP_UNIT_2)
#define	IMP_TAG_CLASS_ID_1 \
	(u8)(IMP_TYPE_CLASS_ID | IMP_ARRAY_FALSE | IMP_UNIT_1)
#define	IMP_TAG_CLASS_ID_2 \
	(u8)(IMP_TYPE_CLASS_ID | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_ATTR_ID_2 \
	(u8)(IMP_TYPE_ATTR_ID | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_ATTR_ID_3 \
	(u8)(IMP_TYPE_ATTR_ID | IMP_ARRAY_FALSE | IMP_UNIT_3)
#define	IMP_TAG_EVENT_ID_2 \
	(u8)(IMP_TYPE_EVENT_ID | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_EVENT_ID_3 \
	(u8)(IMP_TYPE_EVENT_ID | IMP_ARRAY_FALSE | IMP_UNIT_3)
#define	IMP_TAG_ACTION_ID_2 \
	(u8)(IMP_TYPE_ACTION_ID | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_ACTION_ID_3 \
	(u8)(IMP_TYPE_ACTION_ID | IMP_ARRAY_FALSE | IMP_UNIT_3)
#define	IMP_TAG_STATUS_CODE \
	(u8)(IMP_TYPE_STATUS_CODE | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_END_OF_MSG_1 \
	(u8)(IMP_TYPE_END_OF_MSG | IMP_ARRAY_FALSE | IMP_UNIT_1)
#define	IMP_TAG_END_OF_MSG_2 \
	(u8)(IMP_TYPE_END_OF_MSG | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_END_OF_MSG_4 \
	(u8)(IMP_TYPE_END_OF_MSG | IMP_ARRAY_FALSE | IMP_UNIT_4)
#define	IMP_TAG_USER_ID \
	(u8)(IMP_TYPE_USER_ID | IMP_ARRAY_FALSE | IMP_UNIT_4)
#define	IMP_TAG_COMPARATOR \
	(u8)(IMP_TYPE_COMPARATOR | IMP_ARRAY_FALSE | IMP_UNIT_1)
#define	IMP_TAG_APP_ADDR \
	(u8)(IMP_TYPE_APP_ADDR | IMP_ARRAY_TRUE | IMP_UNIT_1)
#define	IMP_TAG_LENGTH \
	(u8)(IMP_TYPE_LENGTH | IMP_ARRAY_FALSE | IMP_UNIT_2)
#define	IMP_TAG_UARIX_1 \
	(u8)(IMP_TYPE_IX_UINT | IMP_ARRAY_TRUE | IMP_UNIT_1)
#define	IMP_TAG_SARIX_1 \
	(u8)(IMP_TYPE_IX_SINT | IMP_ARRAY_TRUE | IMP_UNIT_1)
#define	IMP_TAG_UARIX_2 \
	(u8)(IMP_TYPE_IX_UINT | IMP_ARRAY_TRUE | IMP_UNIT_2)
#define	IMP_TAG_SARIX_2 \
	(u8)(IMP_TYPE_IX_SINT | IMP_ARRAY_TRUE | IMP_UNIT_2)
#define	IMP_TAG_UARIX_4 \
	(u8)(IMP_TYPE_IX_UINT | IMP_ARRAY_TRUE | IMP_UNIT_4)
#define	IMP_TAG_SARIX_4 \
	(u8)(IMP_TYPE_IX_SINT | IMP_ARRAY_TRUE | IMP_UNIT_4)

/* IMP message header, unmarshaled.
 */
#define	IMP_APP_ADDR_BUFFER_LEN	32
struct IMPHDR
{
	tNMLEN	MsgLen;
	tNMLEN	HdrLen;
	tOid	ObjId;
	u16	OpCode;
	tNMSTAT	StatCode;
	u32	Uid;
	u32	Seq;
	u32	TransId1;
	u32	TransId2;
	u16	Access;
	u16	Link;
	u16	AppAddrLen;
	u8	AppAddr[IMP_APP_ADDR_BUFFER_LEN];
	/*
	 * The remaining fields do not get marshaled, but are very useful for
	 * keeping track of request and response message data.
	 */
	u8*	pReqMsg;
	u8*	pRespBody;
	tMID*	pMidTbl;
	void*	pClone;
	tNMLEN	RespBodyLen;
	tCID	CrDelCid;
	u16	CrDelIx;
	u8	CrDelSave;
	u8	ContOffset;
	u8	MidTblLen;
	u8	MidTblOffset;
	u8	RespMbox;
	u8	DoAttrValidate;
	u8	DoClsValidate;
	u8	DoAttrCommit;
	u8	DoClsCommit;
};
typedef struct IMPHDR tIMPHDR;
/*
 * The following definition is an estimate for the maximum size of a marshaled
 * IMP header.  It uses the header structure size for the estimate of the
 * maximal data and array size info to be sent (pretty accurate).  To this it
 * adds the structure size divided by four, in order to add-in at least one
 * more byte per field, for the IMP tags (over-estimated).
 */
#define	IMP_MAX_HDR_LENGTH	(sizeof(tIMPHDR) + (sizeof(tIMPHDR) >> 2))
#define	IMP_MAX_BODY_LENGTH	1024
#define	IMP_MAX_MSG_LENGTH	(IMP_MAX_HDR_LENGTH + IMP_MAX_BODY_LENGTH)

/* IMP event header, unmarshaled.  Notice that the first part of this header
 * is, and MUST BE, the same as the IMP message header.
 */
struct EVHDR
{
	tNMLEN	MsgLen;		/* msg length */
	tNMLEN	HdrLen;		/* msg header length */
	tOid	ObjId;		/* object identifier */
	u16	OpCode;		/* always "event indication" */
	tCID	EvCls;		/* class of event */
	u8	EvNum;		/* number of event, within class */
	u8	EvCode;		/* event/alarm/reply encoding */
	u32	Time;		/* time of (most recent) occurrence: SSE */
	u32	GlEvNum;	/* global event number */
	/*
	 * The following fields are used only for alarm records.
	 */
	u32	Time1;		/* time of first occurrence: SSE */
	u32	Count;		/* number of occurrences: 0=cleared */
	/*
	 * The following fields are used only for action replies.  Their
	 * values echo the values in the action request.
	 */
	u16	ActCls;		/* class of action */
	u8	ActNum;		/* number of action, within class */
	u32	Seq;		/* requester-provided sequence number */
	u32	TransId1;	/* requester-provided data */
	u32	TransId2;	/* requester-provided data */
	u16	AppAddrLen;	/* return address of NM application */
	u8	AppAddr[IMP_APP_ADDR_BUFFER_LEN];
};
typedef struct EVHDR tEVHDR;
#define	IMP_MAX_EVHDR_LENGTH	(sizeof(tEVHDR) + (sizeof(tEVHDR) >> 2))

/* Values for event header EvCode value.  This tells how to marshal and
 * unmarshal the event header.
 */
#define	IMP_EVENT_NORMAL	0
#define	IMP_EVENT_ALARM		1
#define	IMP_EVENT_REPLY		2

/* The following structure is used to store information about the most recent
 * action for which a reply event has yet to be sent.  It is a subset of the
 * information from the original IMP request header.
 */
struct ACINFO
{
	u32	Seq;
	u32	TransId1;
	u32	TransId2;
	u16	AppAddrLen;
	u8	AppAddr[IMP_APP_ADDR_BUFFER_LEN];
	tCID	ActCls;
	u8	ActNum;
	tCID	EvCls;
	u8	EvNum;
	u8	RespMbox;
};
typedef struct ACINFO tACINFO;

/* Externs for Marshal/UnMarshal functions.
 *
 * NOTICE: For port of nmi to Windows 3.1, we use C++ linkage for IMP code.
 * It is NOT in a library, and we need to avoid the Visual C++ (1.51)
 * limitation of only one extern "C" per compilation (which we use up with
 * nmtypes.h).
 */

extern tNMSTAT NmMarshalNull(u8** ppBuf);
extern tNMSTAT NmUnMarshalNull(u8** ppBuf);
extern tNMSTAT NmMarshalU8(u8** ppBuf, u8 Value);
extern tNMSTAT NmMarshalS8(u8** ppBuf, s8 Value);
extern tNMSTAT NmUnMarshalU8(u8** ppBuf, u8* pValue);
#define	NmUnMarshalS8(ppBuf, pValue) \
	NmUnMarshalU8((ppBuf), (u8*)(pValue))
extern tNMSTAT NmMarshalU16(u8** ppBuf, u16 Value);
extern tNMSTAT NmMarshalS16(u8** ppBuf, s16 Value);
extern tNMSTAT NmUnMarshalU16(u8** ppBuf, u16* pValue);
#define	NmUnMarshalS16(ppBuf, pValue) \
	NmUnMarshalU16((ppBuf), (u16*)(pValue))
extern tNMSTAT NmMarshalU32(u8** ppBuf, u32 Value);
extern tNMSTAT NmMarshalS32(u8** ppBuf, s32 Value);
extern tNMSTAT NmUnMarshalU32(u8** ppBuf, u32* pValue);
#define	NmUnMarshalS32(ppBuf, pValue) \
	NmUnMarshalU32((ppBuf), (u32*)(pValue))
extern tNMSTAT NmMarshalByteArray(u8** ppBuf, u8* pArray, u16 ArrayLen,
	u8 Tag);
#define	NmMarshalArrayU8(ppBuf, pArray, ArrayLen) \
	NmMarshalByteArray((ppBuf), (pArray), (ArrayLen), IMP_TAG_UARRAY_1)
#define	NmMarshalArrayS8(ppBuf, pArray, ArrayLen) \
	NmMarshalByteArray((ppBuf), (u8*)(pArray), (ArrayLen), \
	IMP_TAG_SARRAY_1)
extern tNMSTAT NmUnMarshalArrayU8(u8** ppBuf, u8* pArray, u16* pArrayLen,
	u16 BufLen);
#define	NmUnMarshalArrayS8(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalArrayU8((ppBuf), (u8*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmMarshalWordArray(u8** ppBuf, u16* pArray, u16 ArrayLen,
	u8 Tag);
#define	NmMarshalArrayU16(ppBuf, pArray, ArrayLen) \
	NmMarshalWordArray((ppBuf), (pArray), (ArrayLen), IMP_TAG_UARRAY_2)
#define	NmMarshalArrayS16(ppBuf, pArray, ArrayLen) \
	NmMarshalWordArray((ppBuf), (u16*)(pArray), (ArrayLen), \
	IMP_TAG_SARRAY_2)
extern tNMSTAT NmUnMarshalArrayU16(u8** ppBuf, u16* pArray, u16* pArrayLen,
	u16 BufLen);
#define	NmUnMarshalArrayS16(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalArrayU16((ppBuf), (u16*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmMarshalDWordArray(u8** ppBuf, u32* pArray, u16 ArrayLen,
	u8 Tag);
#define	NmMarshalArrayU32(ppBuf, pArray, ArrayLen) \
	NmMarshalDWordArray((ppBuf), (pArray), (ArrayLen), IMP_TAG_UARRAY_4)
#define	NmMarshalArrayS32(ppBuf, pArray, ArrayLen) \
	NmMarshalDWordArray((ppBuf), (u32*)(pArray), (ArrayLen), \
	IMP_TAG_SARRAY_4)
extern tNMSTAT NmUnMarshalArrayU32(u8** ppBuf, u32* pArray, u16* pArrayLen,
	u16 BufLen);
#define	NmUnMarshalArrayS32(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalArrayU32((ppBuf), (u32*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmMarshalString(u8** ppBuf, char* pChars);
extern tNMSTAT NmUnMarshalString(u8** ppBuf, char** ppChars);
extern tNMSTAT NmMarshalObjectId(u8** ppBuf, tOid* pOid);
extern tNMSTAT NmUnMarshalObjectId(u8** ppBuf, tOid* pOid);
extern tNMSTAT NmMarshalClassId(u8** ppBuf, tCID Cid);
extern tNMSTAT NmUnMarshalClassId(u8** ppBuf, tCID* pCid);
extern tNMSTAT NmMarshalClassMember(u8** ppBuf, tCID Cid, u8 Member, u8 Type);
extern tNMSTAT NmUnMarshalClassMember(u8** ppBuf, tCID* pCid, u8* pMember,
	u8 Type);
#define	NmMarshalAttrId(ppBuf, Cid, AttrNumber) \
	NmMarshalClassMember((ppBuf), (Cid), (AttrNumber), IMP_TYPE_ATTR_ID)
#define	NmUnMarshalAttrId(ppBuf, pCid, pAttrNumber) \
	NmUnMarshalClassMember((ppBuf), (pCid), (pAttrNumber), \
	IMP_TYPE_ATTR_ID)
#define	NmMarshalEventId(ppBuf, Cid, EventNumber) \
	NmMarshalClassMember((ppBuf), (Cid), (EventNumber), IMP_TYPE_EVENT_ID)
#define	NmUnMarshalEventId(ppBuf, pCid, pEventNumber) \
	NmUnMarshalClassMember((ppBuf), (pCid), (pEventNumber), \
	IMP_TYPE_EVENT_ID)
#define	NmMarshalActionId(ppBuf, Cid, ActionNumber) \
	NmMarshalClassMember((ppBuf), (Cid), (ActionNumber), IMP_TYPE_ACTION_ID)
#define	NmUnMarshalActionId(ppBuf, pCid, pActionNumber) \
	NmUnMarshalClassMember((ppBuf), (pCid), (pActionNumber), \
	IMP_TYPE_ACTION_ID)
extern tNMSTAT NmMarshalStatusCode(u8** ppBuf, tNMSTAT Code);
extern tNMSTAT NmUnMarshalStatusCode(u8** ppBuf, tNMSTAT* pCode);
extern tNMSTAT NmMarshalEndOfMsg(u8** ppBuf, u32 CkSum, u8 UseCkSum);
extern tNMSTAT NmUnMarshalEndOfMsg(u8** ppBuf, u32* pCkSum, u8* pUseCkSum);
extern tNMSTAT NmMarshalUserId(u8** ppBuf, u32 Uid);
extern tNMSTAT NmUnMarshalUserId(u8** ppBuf, u32* pUid);
extern tNMSTAT NmMarshalComparator(u8** ppBuf, u8 Comp);
extern tNMSTAT NmUnMarshalComparator(u8** ppBuf, u8* pComp);
extern tNMSTAT NmMarshalAppAddr(u8** ppBuf, u8* pAddr, u16 AddrLen);
extern tNMSTAT NmUnMarshalAppAddr(u8** ppBuf, u8* pAddr, u16* pAddrLen,
	u16 BufLen);
extern tNMSTAT NmMarshalLength(u8** ppBuf, tNMLEN Len);
extern tNMSTAT NmUnMarshalLength(u8** ppBuf, tNMLEN* pLen);
extern tNMSTAT NmMarshalImpHeader(u8** ppBuf, tIMPHDR* pImpHdr);
extern tNMSTAT NmUnMarshalImpHeader(u8** ppBuf, tIMPHDR* pImpHdr);
extern tNMSTAT NmUnMarshalImpHeadHead(u8** ppBuf, tIMPHDR* pImpHdr);
extern tNMSTAT NmMarshalEventHeader(u8** ppBuf, tEVHDR* pEvHdr, tNMLEN BodyLen);
extern tNMSTAT NmUnMarshalEventHeader(u8** ppBuf, tEVHDR* pEvHdr);
extern tNMSTAT NmReadImpOpCode(u8* pBuf, u16* pOpCode);
extern tNMSTAT NmWriteImpOpCode(u8* pBuf, u16 OpCode);
extern tNMSTAT NmWriteImpOpAndStatus(u8* pBuf, u16 OpCode, u16 StatusCode);
extern void NmSkipImpField(u8** ppBuf);
extern void NmCopyImpField(u8** ppBuf, u8** ppDst);
extern tNMSTAT NmSetAttrStatus(u8* pBuf, tCID Cid, u8 AttrId, tNMSTAT AttrStat);
/*
 * The following array-oriented functions deal with partial arrays, that is,
 * index/value pairs, vs. values for every index (as above).  The unmarshal
 * functions permit writing directly onto an array or into an array of index/
 * value pairs.
 */
extern tNMSTAT NmMarshalByteArIx(u8** ppBuf, tARu8* pArIx, u16 ArIxLen, u8 Tag);
#define	NmMarshalARu8(ppBuf, pArIx, ArIxLen) \
	NmMarshalByteArIx((ppBuf), (pArIx), (ArIxLen), IMP_TAG_UARIX_1)
#define	NmMarshalARs8(ppBuf, pArIx, ArIxLen) \
	NmMarshalByteArIx((ppBuf), (tARu8*)(pArIx), (ArIxLen), IMP_TAG_SARIX_1)
extern tNMSTAT NmUnMarshalARu8(u8** ppBuf, tARu8* pArIx, u16* pArIxLen,
	u16 BufLen);
#define	NmUnMarshalARs8(ppBuf, pArIx, pArIxLen, BufLen) \
	NmUnMarshalARu8((ppBuf), (tARu8*)(pArIx), (pArIxLen), (BufLen))
extern tNMSTAT NmUnMarshalArrayIxU8(u8** ppBuf, u8* pArray, u16* pArrayLen,
	u16 BufLen);
#define	NmUnMarshalArrayIxS8(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalArrayIxU8((ppBuf), (u8*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmMarshalWordArIx(u8** ppBuf, tARu16* pArIx, u16 ArIxLen,
	u8 Tag);
#define	NmMarshalARu16(ppBuf, pArIx, ArIxLen) \
	NmMarshalWordArIx((ppBuf), (pArIx), (ArIxLen), IMP_TAG_UARIX_2)
#define	NmMarshalARs16(ppBuf, pArIx, ArIxLen) \
	NmMarshalWordArIx((ppBuf), (tARu16*)(pArIx), (ArIxLen), IMP_TAG_SARIX_2)
extern tNMSTAT NmUnMarshalARu16(u8** ppBuf, tARu16* pArIx, u16* pArIxLen,
	u16 BufLen);
#define	NmUnMarshalARs16(ppBuf, pArIx, pArIxLen, BufLen) \
	NmUnMarshalARu16((ppBuf), (tARu16*)(pArIx), (pArIxLen), (BufLen))
extern tNMSTAT NmUnMarshalArrayIxU16(u8** ppBuf, u16* pArray, u16* pArrayLen,
	u16 BufLen);
#define	NmUnMarshalArrayIxS16(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalArrayIxU16((ppBuf), (u16*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmMarshalDWordArIx(u8** ppBuf, tARu32* pArIx, u16 ArIxLen,
	u8 Tag);
#define	NmMarshalARu32(ppBuf, pArIx, ArIxLen) \
	NmMarshalDWordArIx((ppBuf), (pArIx), (ArIxLen), IMP_TAG_UARIX_4)
#define	NmMarshalARs32(ppBuf, pArIx, ArIxLen) \
	NmMarshalDWordArIx((ppBuf), (tARu32*)(pArIx), (ArIxLen), \
	IMP_TAG_SARIX_4)
extern tNMSTAT NmUnMarshalARu32(u8** ppBuf, tARu32* pArIx, u16* pArIxLen,
	u16 BufLen);
#define	NmUnMarshalARs32(ppBuf, pArIx, pArIxLen, BufLen) \
	NmUnMarshalARu32((ppBuf), (tARu32*)(pArIx), (pArIxLen), (BufLen))
extern tNMSTAT NmUnMarshalArrayIxU32(u8** ppBuf, u32* pArray, u16* pArrayLen,
	u16 BufLen);
#define	NmUnMarshalArrayIxS32(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalArrayIxU32((ppBuf), (u32*)(pArray), (pArrayLen), (BufLen))
/*
 * The following array-oriented functions handle either the whole-array or
 * partial-array encoding.
 */
extern tNMSTAT NmUnMarshalAnyArU8(u8** ppBuf, u8* pArray, u16* pArrayLen,
	u16 BufLen);
#define NmUnMarshalAnyArS8(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalAnyArU8((ppBuf), (u8*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmUnMarshalAnyArU16(u8** ppBuf, u16* pArray, u16* pArrayLen,
	u16 BufLen);
#define NmUnMarshalAnyArS16(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalAnyArU16((ppBuf), (u16*)(pArray), (pArrayLen), (BufLen))
extern tNMSTAT NmUnMarshalAnyArU32(u8** ppBuf, u32* pArray, u16* pArrayLen,
	u16 BufLen);
#define NmUnMarshalAnyArS16(ppBuf, pArray, pArrayLen, BufLen) \
	NmUnMarshalAnyArU16((ppBuf), (u16*)(pArray), (pArrayLen), (BufLen))

#endif /* _NMIMP_H_ */
