view src/aci2/mfw/mfw_bte.c @ 662:8cd8fd15a095

SIM speed enhancement re-enabled and made configurable TI's original code supported SIM speed enhancement, but Openmoko had it disabled, and OM's disabling of speed enhancement somehow caused certain SIM cards to start working which didn't work before (OM's bug #666). Because our FC community is much smaller in year 2020 than OM's community was in their day, we are not able to find one of those #666-affected SIMs, thus the real issue they had encountered remains elusive. Thus our solution is to re-enable SIM speed enhancement and simply wait for if and when someone runs into a #666-affected SIM once again. We provide a SIM_allow_speed_enhancement global variable that allows SIM speed enhancement to be enabled or disabled per session, and an /etc/SIM_spenh file in FFS that allows it to enabled or disabled on a non-volatile basis. SIM speed enhancement is now enabled by default.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 May 2020 05:02:28 +0000
parents 93999a60b835
children
line wrap: on
line source

/*
+-------------------------------------------------------------------+
| PROJECT: MMI-Framework (8445)		$Workfile:: mfw_bt.c				$|
| $Author:: NDH						$Revision::  1						$|
| CREATED: 17.04.04					$Modtime:: 17.04.04 17:21			$|
| STATE  : code														 |
+-------------------------------------------------------------------+


   MODULE  : MFW_BT

   PURPOSE : This module contains the functions for MFW Bluetooth Management


*/

#define ENTITY_MFW

#include <string.h>

#if defined (NEW_FRAME)

#include "typedefs.h"
#include "vsi.h"
#include "pei.h"
#include "custom.h"
#include "gsm.h"
#include "prim.h"

#else

#include "STDDEFS.H"
#include "custom.h"
#include "gsm.h"
#include "vsi.h"

#endif

#include "bta_riviera.h"

#include "bta_api.h"
#include "mfw_bt_geh.h"
#include "mfw_bte.h"
#include "mfw_bt_dm.h"
#include "mfw_bt_dg.h"
#include "mfw_bt_ag.h"
#include "mfw_bt_op.h"
#include "mfw_bt_ft.h"
#include "mfw_bt_flash.h"

#include "mfw_utils.h"

/*
** Define Module wide variables
*/
static SHORT Mfw_Bt_Ge_Sigbuf_Id = -1;
static BOOLEAN Mfw_Bt_Ge_InProgress;

static T_MFW_STARTUP_VISIBILITY startup_visibility;

/*
** Local Function Prototypes
*/
static void mfw_bt_send_cb_notify_ind (void);

/*
** Define External variables and references
*/
EXTERN MfwHdr * current_mfw_elem;
/*
** Module Function Definitoins
*/



/*******************************************************************************

 $Function:		mfw_bt_enable

 $Description:		This function will start the whole process of enabling Bluetooth.

 $Returns:		MFW_BT_FAIL if the chip is not stopped or if the generic event handler
 				doesn't start correctly.

 $Arguments:		startup_visibility. Visibility set by the BMI. MFW_BT_DEFAULT_VIS if 
 				using the settings stored in flash. 

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_enable(T_MFW_STARTUP_VISIBILITY startup_visibility )
{
	UINT8 delay_counter = 0;
	T_RV_RET bt_start_status = 0;
	T_MFW_BT_STATUS status;
//	static tBTA_SYS_START_CBACK *fp;
//	fp= (tBTA_SYS_START_CBACK *)&mfw_bt_dm_security_cb;
	
	/* first, enable the event handler */
	status = mfw_bt_ge_enable();
	if( status != MFW_BT_SUCCESS ) 
		return status;
	
	/* start the system */
	if( BTA_SysStart((tBTA_SYS_START_CBACK *)(&mfw_bt_dm_security_cb) ) != RV_OK )
//	if( BTA_SysStart(fp) != RV_OK )
	{	
		MFW_BT_TRACE( "[mfw_bt]: failed to start BT chipset" );
		return MFW_BT_FAIL;	
	}
	/* the start-up procedure has been started. We will receive an 
	event when it is done */		
	MFW_BT_TRACE( "[mfw_bt]: BT is starting" );
	return MFW_BT_SUCCESS;

}




/*  */
/*******************************************************************************

 $Function:		mfw_bt_enable_cb

 $Description:		mfw_bt_enable will cause a BTA_DM_SYS_START_EVT to be sent. At this 
 				moment we call BTA_EnableBluetooth. When we receive 
 				BTA_DM_ENABLE_EVT, we call this function.
 				
 $Returns:		Will send a BMI signal if there is no default name. If the user cancels the 
 				input, BT will then be stopped.
 				Will send a E_BT_ENABLE_CMPL event when the initialization is done. 

 $Arguments:		none 

*******************************************************************************/
void mfw_bt_enable_cb(void)
{
	UINT8* device_name;
	T_MFW_BT_REM_DEVICE *ptr_device_array[MFW_BT_NUM_REM_DEVICE];
	UINT8 number_of_devices;
	T_MFW_BT_ENABLE_CMPL enable_evt_data;

	
	mfw_bt_cb.is_started = TRUE;
	
	/* set device name */
	device_name = mfw_bt_read_local_name( );
	if( *device_name == NULL )
	{
		/* no name yet. Use default one, and ask the user to specify a new one */
		BTA_DmSetDeviceName((char*)MFW_BT_DEVICE_NAME);
		mfw_bt_cb.is_name_requested = TRUE;
		mfw_bt_signal(E_BT_DM_DEV_NAME_REQ, NULL);
	}
	else
		BTA_DmSetDeviceName( (char*)device_name );

	/* set visibility and connectability */
	if( startup_visibility == MFW_BT_DEFAULT_VIS )
	{
		if( mfw_bt_read_visibility( ) == TRUE )
		{
			BTA_DmSetVisibility( BTA_DM_GENERAL_DISC, BTA_DM_CONN);
		}
		else
		{
			BTA_DmSetVisibility( BTA_DM_NON_DISC, BTA_DM_NON_CONN);
		}
	}
	else
	{
		BTA_DmSetVisibility( startup_visibility, BTA_DM_NON_CONN);
	}
	
	
    	/* Update BTA with peer device information stored in NVRAM  */
		/* first, get all the devices */
	mfw_bt_get_device_by_service(0, 
       							    &ptr_device_array[0],
       							    &number_of_devices);

		/* then add these devices to BTA database. */
	for ( ; number_of_devices>0 ; number_of_devices-- )
	{
		if(ptr_device_array[number_of_devices]->link_key_present)
		{
			BTA_DmAddDevice(ptr_device_array[number_of_devices]->bd_addr, 
							    ptr_device_array[number_of_devices]->link_key, 
							    ptr_device_array[number_of_devices]->trusted_services, 
							    ptr_device_array[number_of_devices]->is_trusted);
		}
		else if (ptr_device_array[number_of_devices]->is_trusted)
		{
			BTA_DmAddDevice(ptr_device_array[number_of_devices]->bd_addr, 
							    NULL,
							    ptr_device_array[number_of_devices]->trusted_services,
							    ptr_device_array[number_of_devices]->is_trusted);
		}
	}

	/* initialize all the sub-parts => BT profiles. THIS CODE IS ABSOLUTELY NOT DYNAMIC... Does it
	need to be??? */
	mfw_bt_ag_init();
	mfw_bt_dg_init();
	mfw_bt_op_init();
	mfw_bt_ft_init();
	
	/* finally platform-specific initialization */
	//nothing to do for the time being. 

	/* store the new settings. this stores base conf file */
	mfw_bt_store_status(TRUE);

	enable_evt_data.Success = TRUE;
	mfw_bt_signal(E_BT_ENABLE_CMPL, (void*)&enable_evt_data );
	
	return;

}

/*******************************************************************************

 $Function:		mfw_bt_disable

 $Description:		This function stops the BT system.

 $Returns:		None

 $Arguments:		None

*******************************************************************************/
void mfw_bt_disable(void)
{
	/* disable BT. DM handler will then receive an DISABLE event => will stop the chipset
	and kill the generic event handler. */
	BTA_DisableBluetooth( );

	return;
}



/*******************************************************************************

 $Function:		mfw_bt_init

 $Description:		This function initialises the Mfw Bluetooth Persistent Data on Power Up. 

 $Returns:		None

 $Arguments:		None

*******************************************************************************/
void mfw_bt_init(void)
{

	/*
	** Read the Known Devices from FFS
	*/
	mfw_bt_flash_init( );
	
	/*
	** The rest is down to you Thomas
	*/

	return;
}

/*******************************************************************************

 $Function:		mfw_bt_exit

 $Description:		This function will tidy up any resources used by the Mfw Bluetooth Module
 				on Power Down

 $Returns:		None

 $Arguments:		None

*******************************************************************************/
void mfw_bt_exit(void)
{
	/* nothing to do here... RAM will be automatically cleaned, and the flash wasn't modified */

	return;
}

/*******************************************************************************

 $Function:		mfw_bt_create

 $Description:		This function  initialises an Mfw Bluetooth entity and adds it to the Window Stack

 $Returns:		T_MFW_HND	: A handle for the entity

 $Arguments:		T_MFW_HND		: Parent Window Handle
 				T_MFW_EVENT	: Event Mask of the events to be handled
 				T_MFW_CB		: Callback function to handle the events

*******************************************************************************/
T_MFW_HND mfw_bt_create(T_MFW_HND hWin, T_MFW_EVENT event, T_MFW_CB cbfunc)
{
	T_MFW_HDR *hdr;
	T_MFW_BT  *bt_para;

	MFW_BT_TRACE("mfw_bt_create");

	hdr = (T_MFW_HDR *) mfwAlloc(sizeof (T_MFW_HDR));
	bt_para = (T_MFW_BT *) mfwAlloc(sizeof (T_MFW_BT));

	if (!hdr OR !bt_para)
		return FALSE;

	/*
	* initialisation of the handler
	*/
	bt_para->emask   = event;
	bt_para->handler = cbfunc;

	hdr->data = bt_para;		/* store parameter in node	*/
	hdr->type = MfwTypBt;		/* store type of event handler */

	/*
	* installation of the handler
	*/
	return mfwInsert((T_MFW_HDR *)hWin, hdr);
}

/*******************************************************************************

 $Function:		mfw_bt_delete

 $Description:		This function clears down an Mfw Bluetooth entity and removes it from the
 				Window Stack

 $Returns:		T_MFW_RES	: The result of the function

 $Arguments:		T_MFW_HND	: The Handle of the entity to be removed

*******************************************************************************/
T_MFW_RES mfw_bt_delete(T_MFW_HND hnd)
{
	MFW_BT_TRACE("mfw_bt_delete");

	if (!hnd OR !((T_MFW_HDR *)hnd)->data)
		return MFW_RES_ILL_HND;

	if (!mfwRemove((T_MFW_HDR *)hnd))
		return MFW_RES_ILL_HND;

	mfwFree((U8 *)(((T_MFW_HDR *) hnd)->data),sizeof(T_MFW_BT));
	mfwFree((U8 *)hnd,sizeof(T_MFW_HDR));

	return MFW_RES_OK;
}

/*******************************************************************************

 $Function:		mfw_bt_signal

 $Description:		This function sends the Mfw Bluetooth events from the Mfw to the BMI.

 $Returns:		None

 $Arguments:		T_MFW_EVENT	: The event to be sent to the BMI
 				void *			: Pointer to the Event data

*******************************************************************************/
void mfw_bt_signal(T_MFW_EVENT event, void *para)
{
	UBYTE temp;

	temp = dspl_Enable(0);


	if (mfwSignallingMethod EQ 0)
	{
		/*
		* focus is on a window
		*/
		if (mfwFocus)
		{
			/*
			* send event to sim management
			* handler if available
			*/
			if (mfw_bt_sign_exec (mfwFocus, event, para))
			{
				dspl_Enable(temp);
				return;
			}
		}

		/*
		* actual focussed window is not available
		* or has no network management registration
		* handler, then search all nodes from the root.
		*/
		if (mfwRoot)
			mfw_bt_sign_exec (mfwRoot, event, para);
	}
	else
	{
		MfwHdr * h = 0;

		/*
		* Focus set, then start here
		*/
		if (mfwFocus)
			h = mfwFocus;

		/*
		* Focus not set, then start root
		*/
		if (!h)
			h = mfwRoot;

		/*
		* No elements available, return
		*/
		while (h)
		{
			/*
			* Signal consumed, then return
			*/
			if (mfw_bt_sign_exec (h, event, para))
			{
				dspl_Enable(temp);
				return;
			}

			/*
			* All windows tried inclusive root
			*/
			if (h == mfwRoot)
			{
				dspl_Enable(temp);
				return;
			}

			/*
			* get parent window
			*/
			h = mfwParent(mfwParent(h));

			if (h)
				h = ((MfwWin * )(h->data))->elems;
		}
		
		mfw_bt_sign_exec (mfwRoot, event, para);
		
	}
	
	dspl_Enable(temp);

	return;
}

/*******************************************************************************

 $Function:		mfw_bt_sign_exec

 $Description:		This function sends the Mfw Bluetooth events from the Mfw to the BMI.

 $Returns:		None

 $Arguments:		None

*******************************************************************************/

BOOL mfw_bt_sign_exec (T_MFW_HDR * cur_elem, T_MFW_EVENT event, T_MFW_BT_PARA * para)
{
	MFW_BT_TRACE("mfw_bt_sign_exec");

	while (cur_elem)
	{
		/*
		* event handler is available
		*/
		if (cur_elem->type EQ MfwTypBt)
		{
			T_MFW_BT * bt_data;
			/*
			* handler is CM management handler
			*/
			bt_data = (T_MFW_BT *)cur_elem->data;
			if (bt_data->emask & event)
			{
				/*
				* event is expected by the call back function
				*/
				bt_data->event = event;
				switch (event)
				{
					/*
					** Generic Events
					*/
					case E_BT_ENABLE_CMPL:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_ENABLE_CMPL));
						break;

					case E_BT_DISABLE_CMPL:
						memset(&bt_data->para, 0x00, sizeof(T_MFW_BT_PARA));
						break;

					/*
					** Device Manager Events
					*/
					case E_BT_DM_LINK_UP:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_LINK_UP));
						break;

					case E_BT_DM_LINK_DOWN:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_LINK_DOWN));
						break;

					case E_BT_DM_INQ_RES:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_INQ_RES));
						break;

					case E_BT_DM_INQ_CMPL:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_INQ_CMPL));
						break;

					case E_BT_DM_DISC_RES:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_DISC_RES));
						break;

					case E_BT_DM_DISC_CMPL:
						memset(&bt_data->para, 0x00, sizeof(T_MFW_BT_PARA));
						break;

					case E_BT_DM_PIN_REQ:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_PIN_REQ));
						break;

					case E_BT_DM_AUTH_CMPL:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_AUTH_CMPL));
						break;

					case E_BT_DM_AUTHORIZE_REQ:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_AUTHORIZE_REQ));
						break;

					case E_BT_DM_DEV_NAME_REQ:
						memset(&bt_data->para, 0x00, sizeof(T_MFW_BT_PARA));
						break;

					case E_BT_DM_SIG_STRENGTH_IND:
						memcpy (&bt_data->para, para, sizeof (T_MFW_BT_DM_SIG_STRENGTH_IND));
						break;

				}

				/*
				* if call back defined, call it
				*/
				if (bt_data->handler)
				{
					// store current mfw elem
					current_mfw_elem = cur_elem;

					if ((*(bt_data->handler)) (bt_data->event, (void *)&bt_data->para))
						return TRUE;
				}
			}
		}
		cur_elem = cur_elem->next;
	}
	return FALSE;
}


/*******************************************************************************

 $Function:		mfw_bt_ge_enable

 $Description:		This function initialises the Generic Event Handler, it should be active only
 				when bluetooth is enabled.

 $Returns:		MFW_BT_UNABLE_TO_CREATE_EVT_BUF	: Failed to start - memory problems
 				MFW_BT_SUCCESS					: Started OK, and Ready

 $Arguments:		None

*******************************************************************************/

T_MFW_BT_STATUS mfw_bt_ge_enable (void)
{
	SHORT cbufRetVal;

	MFW_BT_TRACE("mfw_bt_ge_enable");

	/*
	** Try to create the Circular Event Buffer
	*/
	cbufRetVal = mfw_cbuf_create(MFW_BT_MAX_SIG_Q_ENTRIES,		/* Max Entires */
								sizeof(T_MFW_BT_SIGNALS),		/* Item Size */
								FALSE,							/* Don't Overwrite */
								0xFF,							/* Null Character */
								FALSE,							/* Dynamic Buffer */
								(void *)0);						/* Buffer pointer not required */

	if (cbufRetVal == MFW_CBUF_MEM_ALLOC_FAILURE)
	{

		MFW_BT_TRACE("mfw_bt_ge_enable > Buffer Creation Failed with Mem Constraints");

		/*
		** Failed due to memory constraints, try again with half the number of entries
		*/
		cbufRetVal = mfw_cbuf_create(MFW_BT_MAX_SIG_Q_ENTRIES/2,	/* Max Entires */
									sizeof(T_MFW_BT_SIGNALS),		/* Item Size */
									FALSE,							/* Don't Overwrite */
									0xFF,							/* Null Character */
									FALSE,							/* Dynamic Buffer */
									(void *)0);						/* Buffer pointer not required */
		/*
		** All MFW_CBUF error codes are negative, 0 or a positive value from mfw_cbuf_create is a valid buffer Id
		*/
		if (cbufRetVal < 0)
		{

			MFW_BT_TRACE_P1("mfw_bt_ge_enable > Unable to Create Buffer : Error %d", cbufRetVal);

			/*
			** Failed to allocate buffer, return an error
			*/
			return MFW_BT_UNABLE_TO_CREATE_EVT_BUF;
		}
		
	}
	else if (cbufRetVal < 0)
	{

		MFW_BT_TRACE_P1("mfw_bt_ge_enable > Unable to Create Buffer : Error %d", cbufRetVal);

		/*
		** Failed to allocate buffer, return an error
		*/
		return MFW_BT_UNABLE_TO_CREATE_EVT_BUF;
	}


	MFW_BT_TRACE_P1("mfw_bt_ge_enable > Buffer created successfully with Id %d", cbufRetVal);

	/*
	** A buffer has been created, store the Id for future use.
	*/
	Mfw_Bt_Ge_Sigbuf_Id = cbufRetVal;

	return MFW_BT_SUCCESS;

}


/*******************************************************************************

 $Function:		mfw_bt_ge_disable

 $Description:		Disbales the Generic Event Handler, and releases the Dynamic Event Buffer

 $Returns:		None

 $Arguments:		None

*******************************************************************************/
void mfw_bt_ge_disable (void)
{

	MFW_BT_TRACE("mfw_bt_ge_disable");


	/*
	** Ensure the MFW Bluetooth Event handler is initialised
	*/
	if (Mfw_Bt_Ge_Sigbuf_Id < 0)
	{
		MFW_BT_TRACE("mfw_bt_ge_disable > Bluetooth Module Not Initialised");
	}
	else
	{
		mfw_cbuf_delete(Mfw_Bt_Ge_Sigbuf_Id);

		Mfw_Bt_Ge_Sigbuf_Id = -1;
	}
}


/*******************************************************************************

 $Function:		mfw_bt_ge_post_event

 $Description:		This function stores the incoming event in the event buffer, and if required,
 				notifies the MMI Task

 $Returns:		MFW_BT_NOT_INITIALISED	: Fn mfw_bt_ge_enable not called or failed
 				MFW_BT_INVALID_ORIG	: Invalid Originator Id received
 				MFW_BT_INVALID_EVENT	: Invalid Event Id received
 				MFW_BT_INVALID_DATA	: Mismatch between the data pointer and datalen values
 				MFW_BT_FAILED_TO_STORE_EVENT	: Event Buffer Full (check trace)
 				MFW_BT_SUCCESS		: Event Stored successfuly

 $Arguments:		originator		: Identifier for the originating profile that caused the event
 				eventId		: Event Identifier (See BTA Specification)
 				data			: pointer to the event data
 				dataLen		: length of the event data in bytes (must be 0 if data is (void *)0)

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_ge_post_event (T_MFW_BT_ORIGINATORS originator,
										ULONG eventId,
										void * data,
										int dataLen)
{
	T_MFW_BT_SIGNALS	sigBuffer;
	USHORT				numElements;
	SHORT				cbufRetVal;

	MFW_BT_TRACE("mfw_bt_ge_post_event");

	/*
	** Ensure the MFW Bluetooth Event handler is initialised
	*/
	if (Mfw_Bt_Ge_Sigbuf_Id < 0)
	{
		MFW_BT_TRACE("mfw_bt_ge_post_event > Bluetooth Module Not Initialised");
		return MFW_BT_NOT_INITIALISED;
	}

	/*
	** Validate the incoming Parameters
	*/

	if ((originator >= MFW_BT_MAX_ORIGINATOR) ||
	     ((originator & (ULONG)0xFFFF) != 0))
	{
		MFW_BT_TRACE_P1("mfw_bt_ge_post_event > Originator Invalid : 0x%lx", originator);
		return MFW_BT_INVALID_ORIG;
	}

	if (eventId > (ULONG)0xFFFF)
	{
		MFW_BT_TRACE_P1("mfw_bt_ge_post_event > Event Id  Invalid : 0x%lx", eventId);
		return MFW_BT_INVALID_EVENT;
	}

	if ((dataLen < 0) ||
	     ((data == (void *)0) && (dataLen != 0)) ||
	     ((data != (void *)0) && (dataLen == 0)))
	{
		MFW_BT_TRACE_P2("mfw_bt_ge_post_event > Data, DataLen combination Invalid : data 0x%lx, dataLen %d", data, dataLen);
	     return MFW_BT_INVALID_DATA;
	}

	/*
	** Create the Event for storage, which is combined from the OriginatorId and the EventId
	*/
	sigBuffer.event = originator | eventId;

	/*
	** Copy the Signal Data for storage
	*/
	memcpy((void *)&sigBuffer.data, data, dataLen);

	/*
	** Get the existing number of elements in the Event Buffer
	*/
	numElements = mfw_cbuf_num_elements (Mfw_Bt_Ge_Sigbuf_Id);

	/*
	** Post the event to the buffer
	*/
	cbufRetVal = mfw_cbuf_put(Mfw_Bt_Ge_Sigbuf_Id, (void *)&sigBuffer);
	
	if (cbufRetVal != MFW_CBUF_OK)
	{
		/*
		** Unable to store the data
		*/
		MFW_BT_TRACE_P1("mfw_bt_ge_post_event > Unable to store the event : Error %d", cbufRetVal);

		return MFW_BT_FAILED_TO_STORE_EVENT;
	}

	MFW_BT_TRACE("mfw_bt_ge_post_event > Event Successfully Stored");

	/*
	** If required, Post the MMI_BT_CB_NOTIFY_RXD_IND Primitive
	*/
	if ((numElements == 0) &&
	     (Mfw_Bt_Ge_InProgress == FALSE))
	{
		/*
		** Sending Primitive to MMI TASK
		*/
		MFW_BT_TRACE("mfw_bt_ge_post_event > Sending Primitive to MMI TASK");
		mfw_bt_send_cb_notify_ind();
	}
#ifdef MFW_BT_DEBUG
	else
	{
		/*
		** Sending Primitive to MMI TASK
		*/
		MFW_BT_TRACE("mfw_bt_ge_post_event > No need to send Primitive to MMI TASK");
	}
#endif

	return MFW_BT_SUCCESS;
}


/*******************************************************************************

 $Function:		mfw_bt_cb_notify_rxd

 $Description:		This function is called on receipt of the MMI_BT_CB_NOTIFY_IND primitive, it reads
 				the events from the event buffer and passes the details to the appropriate Profile
 				Handler. It will process a Maximum of MFW_BT_MAX_CONSEC_SIG_PROC events
 				before reposting the primitive to the MMI Queue and relinquishing control.

 $Returns:		None

 $Arguments:		None

*******************************************************************************/
void mfw_bt_cb_notify_rxd(void)
{
	T_MFW_BT_SIGNALS sigBuffer;
	T_MFW_BT_ORIGINATORS originatorId;
	T_MFW_BT_STATUS hndlrRetVal;
	ULONG eventId;
	UBYTE numSigsProcessed;
	SHORT cbufRetVal;

	MFW_BT_TRACE("mfw_bt_cb_notify_rxd");

	if (Mfw_Bt_Ge_Sigbuf_Id < 0)
	{
		MFW_BT_TRACE("Mfw_Bt_cb_notify_rxd > Bluetooth Module Not Initialised");
		return;
	}

	/*
	** Initialise Local and Module variables as required.
	*/
	Mfw_Bt_Ge_InProgress = TRUE;
	numSigsProcessed = 0;

	/*
	** While there are events in the Buffer, and the maximum number of signals have not
	** been processed ...
	*/
	while ((numSigsProcessed < MFW_BT_MAX_CONSEC_SIG_PROC) && (mfw_cbuf_num_elements(Mfw_Bt_Ge_Sigbuf_Id) > 0))
	{
		numSigsProcessed++;

		/*
		** Read the event details from the buffer
		*/
		cbufRetVal = mfw_cbuf_get(Mfw_Bt_Ge_Sigbuf_Id, (void *)&sigBuffer);

		if (cbufRetVal != MFW_CBUF_OK)
		{
			Mfw_Bt_Ge_InProgress = FALSE;
			(void)mfw_cbuf_reset(Mfw_Bt_Ge_Sigbuf_Id);
			MFW_BT_TRACE_P1("Mfw_Bt_cb_notify_rxd > Unable to read events from Buffer : Error %d", cbufRetVal);
			return;
		}

		/*
		** Seperate the Originator and Event Id values
		*/
		originatorId = sigBuffer.event & (ULONG)0xFFFF0000;
		eventId = sigBuffer.event & (ULONG)0x0000FFFF;

		/*
		** switch on the originator Id
		*/
		switch (originatorId)
		{
			case MFW_BT_DM_SECURITY:
				hndlrRetVal = mfw_bt_dm_security_hndlr((T_MFW_BT_DM_SEC_EVT)eventId,
													    (T_MFW_BT_DM_SEC_SIG_DATA *)&sigBuffer.data.dmSecSignals);
				break;

			case MFW_BT_DM_SEARCH:
				hndlrRetVal = mfw_bt_dm_search_hndlr((T_MFW_BT_DM_SRCH_EVT)eventId,
													  (T_MFW_BT_DM_SRCH_SIG_DATA *)&sigBuffer.data.dmSrchSignals);
				break;

			case MFW_BT_DG:
				hndlrRetVal = mfw_bt_dg_hndlr((T_MFW_BT_DG_EVT)eventId,
											 (T_MFW_BT_DG_SIG_DATA *)&sigBuffer.data.dgSignals);
				break;

			case MFW_BT_AG:
				hndlrRetVal = mfw_bt_ag_hndlr((T_MFW_BT_AG_EVT)eventId,
											  (T_MFW_BT_AG_SIG_DATA *)&sigBuffer.data.agSignals);
				break;

			case MFW_BT_OPC:
				hndlrRetVal = mfw_bt_opc_hndlr((T_MFW_BT_OPC_EVT)eventId,
											   (T_MFW_BT_OPC_SIG_DATA *)&sigBuffer.data.opcSignals);
				break;

			case MFW_BT_OPS:
				hndlrRetVal = mfw_bt_ops_hndlr((T_MFW_BT_OPS_EVT)eventId,
											   (T_MFW_BT_OPS_SIG_DATA *)&sigBuffer.data.opsSignals);
				break;

			case MFW_BT_FTC:
				hndlrRetVal = mfw_bt_ftc_hndlr((T_MFW_BT_FTC_EVT)eventId,
											  (T_MFW_BT_FTC_SIG_DATA *)&sigBuffer.data.ftcSignals);
				break;

			case MFW_BT_FTS:
				hndlrRetVal = mfw_bt_fts_hndlr((T_MFW_BT_FTS_EVT)eventId,
											  (T_MFW_BT_FTS_SIG_DATA *)&sigBuffer.data.ftsSignals);
				break;

			default:
				MFW_BT_TRACE_P1("mfw_bt_cb_notify_rxd > Invalid Originator 0x%lx", originatorId);
				hndlrRetVal = MFW_BT_SUCCESS;		/* Set the return value to success because an error has already been reported */
				
		}

		if (hndlrRetVal <= 0)
		{
			/* Error reported by the handler, not a lot can be done, expect report it */
			MFW_BT_TRACE_P2("mfw_bt_cb_notify_rxd > Error %d returned from Event handler for Originator 0x%lx", hndlrRetVal, originatorId);
		}
	}

	Mfw_Bt_Ge_InProgress = FALSE;

	/*
	** If there are still signals in the buffer, send another MMI_BT_CB_NOTIFY_RXD_IND primitive
	*/
	if (mfw_cbuf_num_elements(Mfw_Bt_Ge_Sigbuf_Id) > 0)
	{
		MFW_BT_TRACE("Mfw_Bt_cb_notify_rxd > Send the MMI_BT_CB_NOTIFY_IND signal");
		mfw_bt_send_cb_notify_ind();
	}

	return;
}


/**************************************************************************************************
**
** Local Function Definitions
**
**************************************************************************************************/

#define hCommACI _ENTITY_PREFIXED(hCommACI)


/*******************************************************************************

 $Function:		mfw_bt_send_cb_notify_ind

 $Description:		This function posts the MMI_BT_CB_NOTIFY_IND primitive to the MMI Queue

 $Returns:		None

 $Arguments:		None

*******************************************************************************/
static void mfw_bt_send_cb_notify_ind (void)
{
#if defined (NEW_FRAME)
	EXTERN T_HANDLE hCommACI;


	ULONG signal_raw;
#else
	EXTERN T_VSI_CHANDLE hCommACI;
#endif

	PALLOC(bt_cb_notify_ind,MMI_BT_CB_NOTIFY_IND);

	MFW_BT_TRACE("mfw_bt_send_cb_notify_ind");

#if defined (NEW_FRAME)
	PSENDX(ACI,bt_cb_notify_ind);
#else
#if defined (_TMS470)
	vsi_c_send("",hCommACI,D2P(bt_cb_notify_ind),
	        sizeof(T_PRIM_HEADER)+sizeof(T_MMI_BT_CB_NOTIFY_IND));
#else
	PSEND(ACI,bt_cb_notify_ind);
#endif
#endif

	return;

}