/*******************************************************************************
 *
 * File Name : atp_sw_ent.c
 *
 * Functions handling registered SW entities database of the ATP
 *
 * (C) Texas Instruments, all rights reserved
 *
 * Version number	: 0.1      Date : 28-Feb-2000
 *
 * History			: 0.1  - Created by E. Baissus
 *					: 0.9 (3-May-2000) : reviewed 
 *
 * Author			: Eric Baissus : e-baissus@ti.com
 *
 *   (C) Copyright 2000 by Texas Instruments Incorporated, All Rights Reserved				
 ******************************************************************************/
#include "rv/rv_general.h"
#include "rvf/rvf_api.h"
#include "atp/atp_api.h"
#include "atp/atp_i.h"
#include "atp/atp_config.h"

#include <string.h>


/* Number of SW entity which has been registered into ATP excluding GSM */
 T_ATP_SW_ENTITY_ID atp_nb_sw_entity;
 

/* Table gathering the pointers on the different SW entity data structure */
/* If NULL, field is free (initiated in atp_init)*/
/* Note that a static field is used for GSM in order to be able to register the GSM */
/* SW entity even if no memory bank has been allocated to ATP yet */

static T_ATP_SW_ENTITY_STRUCT gsm_sw_entity;
T_ATP_SW_ENTITY_STRUCT * atp_sw_entity_table_p[ATP_MAX_NB_SW_ENTITY+1] = { NULL } ; //First one is reserved for GSM and is NULL at beginning





/******************************************************************************
 * Function name: atp_reg
 *
 * Description : This function is used to register a new SW entity to the ATP entity

 * Parameters :  - name = SW entity name
 *				 - return_path => way to send event to the new registered entity,
 *				 - mode => supported mode of the new registered entity
 *				 - &sw_id_p => pointer on id to use later on to identify the SW entity
 *
 * Return     :   Standard error 
 *					RV_OK or RV_MEMORY_ERR (no more entity can register, or prim MB not GREEN)
 *
 * History			: 0.1 (29-Feb-2000) 
 *					: 0.9 (3-May-2000) : reviewed
 ******************************************************************************/

T_ATP_RET atp_reg(T_ATP_SW_ENTITY_NAME name, T_ATP_CALLBACK return_path, T_ATP_ENTITY_MODE mode ,
				  T_ATP_SW_ENTITY_ID * sw_id_p)
{ 
	T_ATP_SW_ENTITY_STRUCT * sw_struct_p;
	UINT8 i;

    if (atp_get_sw(name,sw_id_p)== RV_OK)
	{
		/* SW entity is already registered */
		atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION,ATP_SAME_ACTION_ALREADY_DONE,NULL);
		return RV_NOT_SUPPORTED;
	}
	
	if (strcmp((char *) name,ATP_GSM_NAME) !=0) // Not GSM registration 
	{
		// Check if a new SW entity can register and if ATP has been started
		if ( (atp_nb_sw_entity==ATP_MAX_NB_SW_ENTITY) || (atp_swe_state != ATP_STARTED))
		{
		atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION,ATP_NO_MORE_RESSOURCE,NULL);
			return RV_NOT_SUPPORTED;
		}
		
		// Get buffer for a new instance
		switch (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_SW_ENTITY_STRUCT),(void **) &sw_struct_p))
		{
			case RVF_GREEN:
				{
					break;
				}
			case RVF_YELLOW:
				{
					rvf_free_buf ((T_RVF_BUFFER *) sw_struct_p);
				}
			default:
				{
					atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION,ATP_MEMORY_ERROR,NULL);
					return RV_MEMORY_ERR; // not enough memory : refuse any new registration
				}
		}
	}
	else
	{
		if (atp_sw_entity_table_p[0]!=NULL)
		{
		atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION,ATP_SAME_ACTION_ALREADY_DONE,NULL);
			return RV_NOT_SUPPORTED; // GSM is already registered 
		}
		sw_struct_p=(&gsm_sw_entity);
	}

	// Initialisation of the structure
	
	// Copy SW entity name
	strcpy((char *) sw_struct_p->sw_entity_name ,(char *) name);
   
	
	// Copy return path information
	sw_struct_p->return_path.callback_func = return_path.callback_func;
	sw_struct_p->return_path.addr_id	   = return_path.addr_id;


	// Copy mode information
	sw_struct_p->mode= mode;

	// Initialize number of open port with the SW entity
	sw_struct_p->nb_open_port=0;

	
	// START : THIS SECTION MUST BE PROTECTED BY  A SEMAPHORE !!!!!!
	// Initialise SW entity table: next field points on new structure
	if (strcmp( (char *) name,ATP_GSM_NAME) !=0) // Not GSM registration 
	{
		i=1;
		while(atp_sw_entity_table_p[i]!=NULL)
		{
			i++;
			if (i>ATP_MAX_NB_SW_ENTITY)
			{
				rvf_free_buf(sw_struct_p);	
		atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION,ATP_MEMORY_ERROR,NULL);
				return RV_MEMORY_ERR;
			}
		}
		atp_nb_sw_entity++;
	}
	else
	{
		i=0; // GSM always got id = 0 
	}
	
	*sw_id_p=i;
	atp_sw_entity_table_p[i]=sw_struct_p;


	// END : THIS SECTION MUST BE PROTECTTED BY  A SEMAPHORE !!!!!!



return RV_OK;
}





/******************************************************************************
 * Function name: atp_dereg
 *
 * Description : This function is used to remove a SW entity to the list of
 * SW entities registered in ATP.
 *
 * Parameters :  - sw_id => id of the SWE
 *
 * Return     :   Standard error 
 *					RV_OK  , 
 *					RV_NOT_READY if a port is still open involving the SW entity
 *					RV_NOT_SUPPORTED if sw_id is already de-registered -> ignore call
 *
 * History			: 0.1 (29-Feb-2000) 
 *					: 0.9 (3-May-2000) : reviewed
 ******************************************************************************/

T_ATP_RET atp_dereg(T_ATP_SW_ENTITY_ID  sw_id)
{ 

T_ATP_SW_ENTITY_STRUCT * sw_entity_p;

	// Check for invalid parameters
	if (sw_id > ATP_MAX_NB_SW_ENTITY)
	{
		return RV_INVALID_PARAMETER;
	}

	// START : THIS SECTION MUST BE PROTECTED BY  A SEMAPHORE !!!!!!
	sw_entity_p=atp_sw_entity_table_p[sw_id];

	if (sw_entity_p==NULL)
	{
		// This entity is no longer registered
		return RV_NOT_SUPPORTED;
	}

	if (sw_entity_p->nb_open_port>0)
	{
		// A port is still open involving this SW entity : refuse de-registration
		atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
		return RV_NOT_READY;
	}

	// Remove SW entity
	atp_sw_entity_table_p[sw_id]=NULL; // free the field
	if (sw_id != 0)
	{
		rvf_free_buf(sw_entity_p); // free the buffer
		atp_nb_sw_entity--;
	}

	// END : THIS SECTION MUST BE PROTECTTED BY  A SEMAPHORE !!!!!!

return RV_OK;
}







/******************************************************************************
 * Function name: atp_get_sw
 *
 * Description : This function is used to get SWE ID from the SWE name
 *
 * Parameters :     - name => name of the SWE to find
 *					- sw_id_p => & of the id of the SWE
 *
 * Return     :   Standard error 
 *					RV_OK  , 
 *					RV_NOT_SUPPORTED if name was not in the SWE ATP list
 *
 * History			: 0.1 (29-Feb-2000) 
 *					: 0.9 (3-May-2000) : reviewed
 ******************************************************************************/
T_ATP_RET atp_get_sw(T_ATP_SW_ENTITY_NAME name,T_ATP_SW_ENTITY_ID * sw_id_p)
{ 
	UINT8 i;
	T_ATP_SW_ENTITY_STRUCT * sw_entity_p;

	for(i=0;i<=ATP_MAX_NB_SW_ENTITY;i++)
	{
		sw_entity_p=atp_sw_entity_table_p[i];
		if (sw_entity_p!=NULL)
		{
			if(strcmp((const char *) name,(const char *) sw_entity_p->sw_entity_name)==0) 
			{   /* Found one SW entity with proper name */
				*sw_id_p=i;
				return RV_OK;
			}
		}
	}
	return RV_NOT_SUPPORTED; // No SW entity had this name
}




/******************************************************************************
 * Function name: atp_reg_info
 *
 * Description : This function is used to get info on a SWE
 *
 * Parameters :  - name => name of the SWE to get info on
 *				 - return : id of the SWE
 *				 - return : SWE mode information 
 *
 * Return     :   Standard error 
 *					RV_OK  , 
 *					RV_NOT_SUPPORTED if name has not been found
 *
 * History			: 0.1 (29-Feb-2000) 
 *					: 0.9 (3-May-2000) : reviewed
 ******************************************************************************/
T_ATP_RET atp_reg_info(T_ATP_SW_ENTITY_NAME name, T_ATP_SW_ENTITY_ID *  sw_id_p, 
					   T_ATP_ENTITY_MODE * mode_p  )
{ 

T_ATP_SW_ENTITY_STRUCT * sw_entity_p;


	// START : THIS SECTION MUST BE PROTECTED BY  A SEMAPHORE !!!!!!
	/* Search related sw entity instance */
	if(atp_get_sw(name,sw_id_p)!=RV_OK)
	{
		return RV_NOT_SUPPORTED;
	}

	sw_entity_p=atp_sw_entity_table_p[*sw_id_p];
	(*mode_p)=sw_entity_p->mode;


	// END : THIS SECTION MUST BE PROTECTTED BY  A SEMAPHORE !!!!!!

return RV_OK;
}



/******************************************************************************
* Function name: atp_dereg_all
*
* Description : De-register all the registered entity
*
* Parameters :  None
*
* Return     :   Always  RV_OK  
*					 
*
* History			
*					: 0.9 (10-Aug-2000) 
******************************************************************************/
T_ATP_RET atp_dereg_all(void)
{ 
	
	UINT8 i;
	
	for(i=0;i<(ATP_MAX_NB_SW_ENTITY+1);i++)
	{
		if (atp_sw_entity_table_p[i] !=NULL)
		{
			/* A SWE is registered in this index */
			if (atp_dereg(i) != RV_OK)
			{
				return RV_INTERNAL_ERR;
			};
		}
	}
	
	return RV_OK;
}





