/*
 * Copyright (c) 1998-2000 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef	_SYS_SYSEVENT_IMPL_H
#define	_SYS_SYSEVENT_IMPL_H

#pragma ident	"@(#)sysevent_impl.h	1.2	00/10/10 SMI"

#include <sys/nvpair.h>

#ifdef	__cplusplus
extern "C" {
#endif

typedef uint64_t se_data_t;

/*
 * The following data structure assist in loading and extracting event
 * header and attribute data into contiguous memory.  Access to all typed
 * data done so on 64-bit boundaries.  *Do Not* alter any of the structures
 * defined below without thorough thought and testing.
 */

/* Attribute name */
typedef struct se_name {
	int32_t		name_sz;
	int32_t		name_pad;
	se_data_t	name;	/* 64-bit aligned offset */
} se_name_t;

/* Attribute value */
typedef struct se_value {
	int32_t		value_type;	/* data type */
	int32_t		value_sz;
	se_data_t	value;		/* data value - 64-bit aligned offset */
} se_value_t;

/* sysevent internal attribute name-value pair stored in contiguous memory */
typedef struct sysevent_attr_impl {
	int32_t		se_attr_sz;	/* Size of attribute data */
	int32_t		se_attr_pad;	/* pad */
	se_data_t	se_attr_name;	/* name of data attribute */
	se_data_t	se_attr_val;	/* value and type of data */
} sysevent_attr_impl_t;

/* Attribute list states */
#define	ATTR_DETACHED	0
#define	ATTR_ATTACHED	1

/*
 * The following type defintions describe a sysevent object that is
 * generated by a call to sysevent_alloc and sent to userland.
 */

/*
 * sysevent event header information -
 * 	contained in every event generated.  The header and the event
 *	must remain 64-bit aligned.  The header, up to the attribute
 *	offset, can be contained in a single cache line.
 */
typedef struct sysevent_hdr {
	sysevent_id_t	se_id;		/* unique identifier */
	uint32_t	se_version;	/* version of this data structure */
	uint32_t	se_flag;
	uint32_t	se_class;	/* event class id - reserved */
	uint32_t	se_subclass;	/* event subclass id - reserved */
	int32_t		se_payload_sz;	/* size of attr data + strings */
	uint16_t	se_subclass_off; /* offset to subclass string */
	uint16_t	se_pub_off;	/* offset to publisher string */
	uint64_t	se_attr_off;	/* pointer or offset to attr data */
} sysevent_hdr_t;

/* sysevent event buffer - 64-bit aligned offsets */
typedef struct sys_event_impl {
	sysevent_hdr_t	se_header;
	se_data_t	se_class_name;	/* class string in contig memory */
	se_data_t	se_subclass_name; /* subclass string in contig memory */
	se_data_t	se_pub;		/* publisher string in contig mem */
	se_data_t 	se_attr_buf;	/* contiguous attribute memory	*/
} sysevent_impl_t;

/* Helpful defines */
#define	seh_version	se_header.se_version
#define	seh_class	se_header.se_class
#define	seh_subclass	se_header.se_subclass
#define	seh_seq		se_header.se_id.eid_seq
#define	seh_time	se_header.se_id.eid_ts
#define	seh_subclass_off se_header.se_subclass_off
#define	seh_pub_off	se_header.se_pub_off
#define	seh_attr_off	se_header.se_attr_off
#define	seh_payload_sz	se_header.se_payload_sz
#define	seh_flag	se_header.se_flag

/* Event buffer version */
#define	SYS_EVENT_VERSION	0
/* Event buffer flags */
#define	SE_PACKED_BUF	1

#define	SYSEVENT_IMPL(ev)	((sysevent_impl_t *)(void *)(ev))
#define	SE_VERSION(ev)		(SYSEVENT_IMPL(ev)->seh_version)
#define	SE_CLASS(ev)		(SYSEVENT_IMPL(ev)->seh_class)
#define	SE_SUBCLASS(ev)		(SYSEVENT_IMPL(ev)->seh_subclass)
#define	SE_SEQ(ev)		(SYSEVENT_IMPL(ev)->seh_seq)
#define	SE_TIME(ev)		(SYSEVENT_IMPL(ev)->seh_time)
#define	SE_SUBCLASS_OFF(ev)	(SYSEVENT_IMPL(ev)->seh_subclass_off)
#define	SE_PUB_OFF(ev)		(SYSEVENT_IMPL(ev)->seh_pub_off)
#define	SE_PAYLOAD_SZ(ev)	(SYSEVENT_IMPL(ev)->seh_payload_sz)
#define	SE_FLAG(ev)		(SYSEVENT_IMPL(ev)->seh_flag)
#define	SE_SIZE(ev)		(sizeof (sysevent_impl_t) + SE_PAYLOAD_SZ(ev))
#define	SE_CLASS_NAME(ev)	((char *)&(SYSEVENT_IMPL(ev)->se_class_name))
#define	SE_SUBCLASS_NAME(ev)	((char *)((caddr_t)(ev) + SE_SUBCLASS_OFF(ev)))
#define	SE_PUB_NAME(ev)		((char *)((caddr_t)(ev) + SE_PUB_OFF(ev)))

/*
 * Attribute data can be stored in contiguous memory or
 * as a list of attribute data elements.  The storage format is determined
 * by the SE_PACKED_BUF flag in the event buffer flags.
 *
 */

/* 64-bit boundary alignment function */
#define	SE_ALIGN(x)	((((ulong_t)x) + 7ul) & ~7ul)

/* Access to unpacked attribute list */
#define	SE_ATTR_PTR(ev)		(SYSEVENT_IMPL(ev)->seh_attr_off)

/* Offset to packed attribute data */
#define	SE_ATTR_OFF(ev)	SE_PUB_OFF(ev) + SE_ALIGN(strlen(SE_PUB_NAME(ev)) + 1)

/* syseventd door */
#define	LOGEVENT_DOOR_UPCALL	"/etc/sysevent/sysevent_door"

/*
 * door upcall data structures
 */
typedef struct log_event_upcall_arg {
	int32_t retcode;
	sysevent_impl_t buf;
} log_event_upcall_arg_t;

typedef struct log_eventq {
	struct log_eventq	*next;
	log_event_upcall_arg_t	arg;
} log_eventq_t;

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_SYSEVENT_IMPL_H */
