/*
 ******************************************************************************
 *  Copyright 1998 DeltaLink bv. All Rights Reserved.
 ******************************************************************************
 *
 * DeltaLink Communication header file
 *
 * File:  sapi.h
 *
 * This file contains the definitions for the H1 communication layer. This a
 * general file which must exist for every Protocol Driver. 
 *
 */

#ifndef _SAPI_DEFS_INCLUDED
#define _SAPI_DEFS_INCLUDED 1

#define TASK_NAME         "SAPI_S7"                   /* Task name */
#define INI_FILE          "sapi_s7.txt"               /* initialisation file */
#define TASK_CT           "sapi_s7.ct"                /* CT file for task */
#define TASK_DESC         "Siemens SAPI Protocol Driver" /* Task description */
#define TASK_NUMBER       SAPIS7                      /* Task DeltaLink ID */ 

#define SUBTASK_NAME      "SAPI7SUB"                  /* Task name */
#define SUBTASK_DESC      "Siemens SAPI Protocol Driver" /* Task description */

#define RX_BUF_SIZE				8192												/* buffer size */

#define BUFFER_SIZE				8192												/* buffer size */


/*#define SAPI_WAIT					15000												* max. wait time (msec) for device to release */
#define SAPI_WAIT					INFINITE										/* max. wait time (msec) for device to release */

#define S7_CP_DEVICE			0			
#define S7_CPU_DEVICE			1

#define CSTART										0									
#define CSTOP  										1									
#define MAX_CYCLIC_REQ_PENDING		64									/* maximum of cyclic requests pending */


#define USER										0									
#define INTERNAL								1
/*
 * define SAPI function macros
 */
#define Set_Con_Name( d, n, fnc)          strcpy( (d)->connection[fnc], (n))

/*
 * set the connecting state
 */
#define CS_DISCONNECTED   -1
#define CS_CONNECTING      0
#define CS_CONNECTED       1

/*
 * define SAPI S7 driver errors
 */
#define	PD_HEADER_ERROR				300											/* header validation */

#define PD_READ_DISABLED	    850											/* functionality has been disabled */
#define PD_WRITE_DISABLED	    851											/* functionality has been disabled */
#define PD_RCV_DISABLED				852

#define PD_BIT_ADDRESSING     853											/* invalid addressing method on bit boundary */
#define PD_EXWRITE            854											/* exception write not possible to destination */
#define PD_CLOSED             855											/* SAPI_S7 driver has shutdown */
#define PD_UNKOWN_ERROR	      856											/* an unknown error occured in the comm layer */
#define PD_NO_DATA            857											/* no data received */

#define PD_NOT_ENCODE					859

#define PD_DISCONNECTED				861                     /* no connection established */

#define PD_NOBOARD    				862                     /* board not defined */
#define PD_NOCONNECTION				863											/* connection not defined */

#define PD_CREAD_INTERVAL			864											/* wrong cyclic read interval */
#define PD_START_CYCLIC       865
#define PD_STOP_CYCLIC        866
#define PD_MAX_CYCLIC         867

#define PD_SYNC_ERROR         870											/* wrong response received with request */
#define PD_REQ_TIMEOUT        871											/* request timed out */

typedef HANDLE SEM;

/*
 * S7 board information
 */
typedef struct _vfd
{
  char    board[ MAX_TAG_NAME +MAX_DIM_LENGTH +2 ];		/* board name constant */
  char    name  [ S7_MAX_NAMLEN +1 ];									/* virtual domain */

	ord32		cp_descr;  																	/* cp_decr handle - return value */

} VFD;

/*
 * S7 device information
 */
typedef struct _device
{
  char    name[ 18 ];								/* logical device name of remote module */
	char    board_name[ MAX_TAG_NAME +MAX_DIM_LENGTH +2 ];	/* board name constant */
	int     board_id;                 /* board name present in PC */
	char		connection[ 20 ];					/* connection names as defined in softnet */
	int     ctype;										/* type of connection, CP or CPU */
	
	ord32		cp_descr; 								/* cp_decr handle - return value */
	ord32		descr;  		  						/* cp_decr handle - return value */
	ord16		cref;											/* reference for the connection read, write, rcv*/
	
	ushort	encode;										/* DB number for the encoded write */

	TAG			status;										/* status of the device */
	TAG			c_count;									/* cyclic count of resources */

	char		disable[ 3 ][ 2 ];  			/* disable flags read, write, rcv */
	char		connect;									/* connect status flag */
	char		cyclic_count;							/* cyclic resources count var */

	char 		*buffer[ 3 ];							/* communication buffers read, write, rcv*/
	 
  IMXDS		**dataset;								/* array of all datasets defined */
  ushort	Nr_Datasets;							/* total number of datasets */

	SEM			grab[ 3];									/* read, write and recv semaphore */
  int  		current[ 3 ];							/* current actual dataset on device */

	int     brcv[ 3];                 /* just mark if brcv_init is done */

  struct _ds_info	*cyclic[2][ MAX_CYCLIC_REQ_PENDING ]; /* buffer for cyclic read requests */
	char		cyclic_pending[2];
	char		cyclic_head[2],
					cyclic_tail[2];

} DEVICE;


/*
 * additional dataset information
 */
typedef struct _ds_info
{
	DEVICE  *device;			/* pointer to device in which this dataset resides */

  ushort	max_msg;      /*  max. number of messages in decoder mailbox */

	ushort	type;					/* data type of dataset */
	ushort	db_nr;				/* data block number */

	ord16   ds_index;			/* index to dataset in the dataset pointer array */

	int     reading;      /* dataset is currently being read, discard incoming read requests */

	ANA     cyclic_read;  /* value indicating if cyclic read is active */

} DS_INFO;

/* 
 * decoder defintion information
 */
typedef struct _xlator           /*  definition off all used decoders */
{

  TAG    mbx;                    /*  decoder Mailbox tag */
  ushort max_msg;                /*  max. number of messages in decoder mailbox */

} XLATOR;

/*
 * Task global variables
 */
extern TASK_ID      *Task_fl;                   /* FactoryLink thread task information */
extern TASK_ID      Task_win;                   /* win call-back thread task information */
extern TASK_ID      Callback;                   /* win call-back thread task information */

extern VFD						*Vfd;
extern int						Nr_vfd;

extern IMXSYSTEM    Imxsys;											/* system parameters of the IMX library */
extern IMXSYSTEM    Thr_system;
extern IMXSYSTEM    Cb_system;

extern FLMSG          Imx_buf;                    /* buffer for receiving with IMX */
extern FLMSG          Sapi_buf;                   /* buffer for receiving SAPI events */

extern DEVICE				**Device;										/* array of defined devices */
extern ushort				Nr_devices;

extern XLATOR 			*Decoder;										/* array of all decoders defined */
extern ushort				Nr_decoders;								/* total number of decoders */

extern IMXDS				**Ds;												/* array of all datasets defined */
extern ushort				Nr_ds;											/* total number of datasets */

extern H1_HDR				_H1_read;
extern H1_HDR				_H1_write;
extern H1_HDR				_H1_ack;

/* SAPI FL functions */

void  ctload					( void);

void  error_response	( DEVICE *, IMXDS *, int, int);

void	connect_all     ( TASK_ID *);
void	shutdown_all    ( TASK_ID *);

/* SAPI event functions */

int		imx_event					( IMXDS *);
void	IMX_Error_Response( IMXDS *, int, u16);

int disable_fnc				( void *, VAL);						
int set_board					( void *, VAL);						
int cyclic_read       ( void *, VAL);

/* SAPI communication functions */

int     sapi_shutdown         ( void );
int     sapi_connect  		    ( DEVICE *, int );
int     sapi_connect_rsp	    ( DEVICE * );
int     sapi_disconnect		    ( DEVICE *, int );
int     sapi_read					    ( IMX_DEVICE *, int );
int     sapi_write				    ( IMX_DEVICE *, int);
int     sapi_read_rsp			    ( IMXDS *);
int     sapi_write_rsp		    ( IMXDS *);
int     sapi_cycl_read_rsp    ( IMXDS *);
int     sapi_recv_rsp			    ( DEVICE *);
int     sapi_board_init		    ( TASK_ID *, DEVICE *);
int     sapi_start_cyclic     ( TASK_ID *, DS_INFO *);
int     sapi_stop_cyclic      ( TASK_ID *, DS_INFO *);
int			sapi_check_cyclic			( DEVICE *);

int     cyclic_read_task      ( TASK_ID *, DS_INFO *, VAL);

int     validate_H1_header    ( H1_HDR *, int *);
int     sapi_dispatch         ( ord32 );
int     sapi_ds_search        ( H1_HDR *, DEVICE *, int);
int     search_device 		    ( ord32, ord16, DEVICE ** );
int     encode						    ( DEVICE *, IMXDS *, ENCODE *);
int     Compare_Ds				    ( H1_HDR *, H1_HDR *);
void    update_status         ( TASK_ID *, DEVICE *, ANA );
void    update_count          ( TASK_ID *, DEVICE *, ANA );

/* SAPI semaphore functions */

int create_sem                ( DEVICE * );
int destroy_sem               ( DEVICE * );

int grab_connection           ( DEVICE *, int );
int release_connection        ( DEVICE *, int );

/* SAPI window functions */

int win_set_callback (	ord32 );

/* SAPI macros for building the H1 header */

#define S7_Get_Word_H2L( w)            ( (*( ushort *)(w) >> 8) & 0x00ff) | \
                                       ( (*( ushort *)(w) << 8) & 0xff00)
#define S7_Set_Word_H2L( w, v)         ( *( ushort *)(w) = ((( ushort )(v) >> 8) & 0x00ff) | \
                                                        ((( ushort )(v) << 8) & 0xff00))
#define S7_Get_Word_L2H( w)            (*( ushort *)(w))
#define S7_Set_Word_L2H( w, v)         (*( ushort *)(w) = ( ushort)(v))


#define POINTER_UP( p )				{ if( (p) >= MAX_CYCLIC_REQ_PENDING -1 ) (p) = 0; \
															  else (p)++; }

#endif