/*******************************************************************************
 * Copyright (c) 2005, 2006 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:
 *    Andy Kaylor, Intel - Initial API and Implementation
 *
 * $Id: TPTPBaseTL.h,v 1.6 2006/12/04 18:37:16 akaylor Exp $
 *
 *******************************************************************************/ 

#ifndef __TPTPBASETL_H__
#define __TPTPBASETL_H__

#include "tptp/MsgPipeline.h"
#include "tptp/hashtable.h"

typedef enum
{
	TPTP_TL_THREAD_NOT_STARTED = 0,
	TPTP_TL_THREAD_RUNNING,
	TPTP_TL_THREAD_STOPPED
} tl_thread_state_t;

typedef struct
{
	tptp_object*                       cmo;
	addConnectionEntry_ptr_t           addConnection;
	removeConnectionEntry_ptr_t        removeConnection;
	addDataConnectionEntry_ptr_t       addDataConnection;
	addDirectDataConnectionEntry_ptr_t addDirectDataConnection;
	removeDataConnectionEntry_ptr_t    removeDataConnection;
	logEventEntry_ptr_t                logEvent;
} ac_interface_t;

typedef struct
{
	tptp_object*          nexto;
	processMessage_ptr_t  processMessage;
} control_partner_t;

typedef struct
{
	tptp_object*    nexto;
	tptp_uint32     connectionID;
	tptp_uint32     descriptor;
	sendData_ptr_t  sendData;
} data_partner_t;

typedef struct
{
	tptp_uint32     connectionID;
	void*           implData;
} tl_control_connection_t;

typedef struct
{
	tptp_uint32     connectionID;
	data_partner_t  dataPartner;
	void*           implData;
} tl_data_connection_t;


typedef struct
{
	tptp_uint32        transportID;
	tptp_string*       displayName;
	ac_interface_t	   ac;
	control_partner_t  controlPartner;
	tl_thread_state_t  processingThreadState;
    HashTable*         controlConnectionTable;
    HashTable*         dataConnectionTable;
	Lock_t             dataConnectionLock;
    HashTable*         contextDataTable;
	void*              implData;
} tl_state_data_t;

/* Base Implementations of TL interface functions */
tptp_int32 baseTL_createTransportListener( tptp_object* cmo, transport_layer_data_t * pTransportData, tptp_object* tlo, tptp_string* displayName );
tptp_int32 baseTL_destroyTransportListener( tptp_object* tlo );
tptp_int32 baseTL_startTransportListener(tptp_object* tlo, RUN_FUNC_TYPE processingFunc);
tptp_int32 baseTL_stopTransportListener(tptp_object* tlo);
tptp_int32 baseTL_setProcessMessageFunc(tptp_object* tlo, tptp_object* nexto, processMessage_ptr_t func );
tptp_int32 baseTL_setIncomingDataFunc( tptp_object* tlo, tptp_uint32 connectionID, tptp_uint32 partnerID, tptp_object* partner, sendData_ptr_t newDataFunc );

/* Note that sendMessage, sendData, terminateConnection and 
 * terminateDataConnection have no base implementation */

/* Additional helper functions */
tptp_int32 baseTL_addControlConnectionEntry(tl_state_data_t* stateData, tptp_uint32 connectionID, void* implData);
tptp_int32 baseTL_addDataConnectionEntry(tl_state_data_t* stateData, tptp_uint32 connectionID, void* implData);
tptp_int32 baseTL_removeControlConnectionEntry(tl_state_data_t* stateData, tptp_uint32 connectionID);
tptp_int32 baseTL_removeDataConnectionEntry(tl_state_data_t* stateData, tptp_uint32 connectionID);
tptp_int32 baseTL_storeContextData(tl_state_data_t* stateData, tptp_int32 contextID, void* contextData);
tptp_int32 baseTL_getContextData(tl_state_data_t* stateData, tptp_int32 contextID, void** contextData);
tptp_int32 baseTL_releaseContextData(tl_state_data_t* stateData, tptp_int32 contextID);
tptp_uint32 baseTL_getNextContextID();

#define TPTP_BASETL_OBJECT_ID_TRANSFORM   0x100001

#define TPTP_BASETL_MAKE_OBJECT_ID(p)  ((unsigned int)p & TPTP_BASETL_OBJECT_ID_TRANSFORM)


/* This structure allows us to peek at the first field of context data 
      to determine what structure we should be using.   All other context
	  data structures should use contextDataType as their first field */
typedef struct
{
	tptp_uint32     contextDataType;
} generic_context_t;

/* This structure allows us to peek at the first three field of context data 
      for commands that use a semaphore to wait for response. All other context
	  data structures which are used in this was should use these four fields
      as their first four fields */
typedef struct
{
	tptp_uint32     contextDataType;
	Semaphore_t     completionSemaphore;
	tptp_uint32     timeout;
	tptp_int32      status;
} generic_wait_context_t;

/* These values are used in context structures */
#define BASETL_STATUS_PENDING 1
#define BASETL_STATUS_TIMEOUT 2

void baseTL_startTimeoutThread( generic_wait_context_t *contextData );

/* TODO: Move these to a common location and give them values */
#define TPTP_ERROR_INVALID_PARAMETER -1
#define TPTP_ERROR_MISSING_INTERFACE_FUNCTIONS -1
#define TPTP_ERROR_OUT_OF_MEMORY -1
#define TPTP_ERROR_CONNECTION_NOT_FOUND -1

#endif /* __TPTPBASETL_H__ */
