/*******************************************************************************
 * Copyright (c) 2005, 2009 Intel Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Hoang M. Nguyen, Intel - Initial API and implementation
 * $Id: dime.h,v 1.15 2009/08/26 14:59:52 jwest Exp $ 
 *
 *******************************************************************************/ 
#ifndef dime_h
#define dime_h

#ifdef __cplusplus
extern "C" {
#endif

#include <tptp/TPTPTypes.h>

#define DIME_VERSION 0x01
#define TYPE_T_UNCHANGED 	0x00
#define TYPE_T_MEDIA 		0x01
#define TYPE_T_ABS_URI 		0x02
#define TYPE_T_UNKNOWN 		0x03
#define TYPE_T_NONE 		0x04
#define TYPE_T_RESERVED		0x04

#define RESRVD_VALUE		0x00    //Must be set to 0

/* These offset's are used for swapping bytes for endian issues */
#define OPTIONS_LENGTH_OFFSET 2
#define ID_LENGTH_OFFSET      4
#define TYPE_LENGTH_OFFSET    6
#define DATA_LENGTH_OFFSET    8

/* The layout of bit fields in structs is dependent on a platform/compiler. 
 * This may need to be revisited in the future and changed, depending on the platform
 * So far, this only affects the FileTransferAgent ... the getFile() implementation
 * in the sample java client never returns because the bits are in the wrong order
 * on some platforms (eg Solaris, AIX, Linux390)
 */
typedef struct {
#if !defined(_SOLARIS) && !defined(MVS)
	unsigned int version : 5;	// 5 bits		0 word
	unsigned int mb : 1;		// 1 bit
	unsigned int me : 1;		// 1 bit
	unsigned int cf : 1;		// 1 bit
#else
	unsigned int cf : 1;            // 1 bit
	unsigned int me : 1;            // 1 bit
	unsigned int mb : 1;            // 1 bit
	unsigned int version : 5;       // 5 bits
#endif
	unsigned int type_t : 4;		// 4 bits
	unsigned int resrvd : 4;		// 4 bits
	unsigned int options_length : 16;	// 16 bits
	unsigned int id_length : 16;		// 16 bits		1nd word
	unsigned int type_length : 16;		// 16 bits	
	unsigned int data_length : 32;		// 32 bits		2rd word
} DIME_HEADER_T;
typedef DIME_HEADER_T *DIME_HEADER_PTR_T;

tptp_int32 init_dime_header(DIME_HEADER_PTR_T p);
tptp_int32 construct_dime_file_transfer(DIME_HEADER_PTR_T *p, char *fileName, tptp_int32 length);
tptp_int32 construct_dime_file_transfer_error(DIME_HEADER_PTR_T *p, char *fileName, tptp_int32 length, int errCode);
tptp_int32 construct_dime_console(DIME_HEADER_PTR_T *p,  PID processId, tptp_int32 consoleType, tptp_int32 dataSize) ;
char *get_dime_id(DIME_HEADER_PTR_T p);
void free_dime(DIME_HEADER_PTR_T p);

PID get_dime_process_id(DIME_HEADER_PTR_T p);
tptp_int32 get_dime_console_type(DIME_HEADER_PTR_T p);
tptp_int32 get_dime_length(DIME_HEADER_PTR_T p);
tptp_int32 is_valid_header(DIME_HEADER_PTR_T p, tptp_int32 amount_read);
tptp_int32 make_dime_header(char *buffer);

#define INIT_DIME_HEADER(x) init_dime_header(x)

#define MAKE_NBO_DIME_HEADER(b) make_dime_header(b)
#define MAKE_DIME_HEADER(b) make_dime_header(b)
#define MAKE_DIME_FILE_TRANSFER(xp, b, c) construct_dime_file_transfer(xp, b, c)
#define MAKE_DIME_FILE_TRANSFER_ERROR(xp, b, c, e) construct_dime_file_transfer_error(xp, b, c, e)
#define MAKE_DIME_CONSOLE(xp, id, ct, ds) construct_dime_console(xp, id, ct, ds)
#define FREE_DIME(x)	free_dime(x)
#define DIME_START(xp) xp->mb = 0x1;
#define DIME_END(xp) xp->me   = 0x1;

#define DIME_MESSAGE_MIDDLE 0
#define DIME_MESSAGE_START_END 1
#define DIME_MESSAGE_START 2
#define DIME_MESSAGE_END 3



#define IS_DIME_END_RECORD(xp) xp->me == 0x1
#define IS_DIME_BEGIN_RECORD(xp) xp->mb == 0x1
#define GET_DIME_DATA_OFFSET(xp) xp->id_length + sizeof(DIME_HEADER_T)
#define GET_DIME_ID(xp) get_dime_id(xp)
#define GET_DIME_LENGTH(xp) get_dime_length(xp)
#define GET_DIME_PROCESS_ID(xp) get_dime_process_id(xp)
#define GET_DIME_CONSOLE_TYPE(xp) get_dime_console_type(xp)

#ifdef __cplusplus
}
#endif

#endif 
